org.apache.jackrabbit.jcr2spi.RepositoryImpl Maven / Gradle / Ivy
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.jackrabbit.jcr2spi;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Map;
import java.util.HashMap;
import javax.jcr.Credentials;
import javax.jcr.LoginException;
import javax.jcr.NoSuchWorkspaceException;
import javax.jcr.Repository;
import javax.jcr.RepositoryException;
import javax.jcr.Session;
import javax.jcr.Value;
import javax.jcr.ValueFactory;
import javax.jcr.NamespaceException;
import javax.naming.Context;
import javax.naming.Name;
import javax.naming.NamingException;
import javax.naming.RefAddr;
import javax.naming.Reference;
import javax.naming.Referenceable;
import javax.naming.StringRefAddr;
import javax.naming.spi.ObjectFactory;
import org.apache.jackrabbit.commons.AbstractRepository;
import org.apache.jackrabbit.jcr2spi.config.RepositoryConfig;
import org.apache.jackrabbit.spi.SessionInfo;
import org.apache.jackrabbit.spi.XASessionInfo;
import org.apache.jackrabbit.spi.QValue;
import org.apache.jackrabbit.spi.commons.conversion.NamePathResolver;
import org.apache.jackrabbit.spi.commons.conversion.DefaultNamePathResolver;
import org.apache.jackrabbit.spi.commons.namespace.NamespaceResolver;
import org.apache.jackrabbit.spi.commons.value.ValueFormat;
import org.apache.jackrabbit.value.ValueFactoryImpl;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* RepositoryImpl
...
*/
public class RepositoryImpl extends AbstractRepository implements Referenceable {
private static Logger log = LoggerFactory.getLogger(RepositoryImpl.class);
// configuration of the repository
private final RepositoryConfig config;
private final Map descriptors;
private Reference reference = null;
private RepositoryImpl(RepositoryConfig config) throws RepositoryException {
this.config = config;
// dummy value factory and dummy resolver as descriptors are not
// expected to contain Name or Path values.
ValueFactory vf = ValueFactoryImpl.getInstance();
NamePathResolver resolver = new DefaultNamePathResolver(new NamespaceResolver() {
public String getURI(String prefix) throws NamespaceException {
return prefix;
}
public String getPrefix(String uri) throws NamespaceException {
return uri;
}
});
Map descr = config.getRepositoryService().getRepositoryDescriptors();
descriptors = new HashMap(descr.size());
for (String key : descr.keySet()) {
QValue[] qvs = descr.get(key);
Value[] vs = new Value[qvs.length];
for (int i = 0; i < qvs.length; i++) {
vs[i] = ValueFormat.getJCRValue(qvs[i], resolver, vf);
}
descriptors.put(key, vs);
}
}
public static Repository create(RepositoryConfig config) throws RepositoryException {
return new RepositoryImpl(config);
}
//---------------------------------------------------------< Repository >---
/**
* @see Repository#getDescriptorKeys()
*/
public String[] getDescriptorKeys() {
return descriptors.keySet().toArray(new String[descriptors.keySet().size()]);
}
/**
* @see Repository#getDescriptor(String)
*/
public String getDescriptor(String key) {
Value v = getDescriptorValue(key);
try {
return (v == null) ? null : v.getString();
} catch (RepositoryException e) {
log.error("corrupt descriptor value: " + key, e);
return null;
}
}
/**
* @see Repository#getDescriptorValue(String)
*/
public Value getDescriptorValue(String key) {
Value[] vs = getDescriptorValues(key);
return (vs == null || vs.length != 1) ? null : vs[0];
}
/**
* @see Repository#getDescriptorValues(String)
*/
public Value[] getDescriptorValues(String key) {
if (!descriptors.containsKey(key)) {
return null;
} else {
return descriptors.get(key);
}
}
/**
* @see Repository#isSingleValueDescriptor(String)
*/
public boolean isSingleValueDescriptor(String key) {
Value[] vs = descriptors.get(key);
return (vs != null && vs.length == 1);
}
/**
* @see Repository#login(javax.jcr.Credentials, String)
*/
public Session login(Credentials credentials, String workspaceName) throws LoginException, NoSuchWorkspaceException, RepositoryException {
SessionInfo info = config.getRepositoryService().obtain(credentials, workspaceName);
try {
if (info instanceof XASessionInfo) {
return new XASessionImpl((XASessionInfo) info, this, config);
} else {
return new SessionImpl(info, this, config);
}
} catch (RepositoryException ex) {
config.getRepositoryService().dispose(info);
throw ex;
}
}
//------------------------------------------------------< Referenceable >---
/**
* @see Referenceable#getReference()
*/
public Reference getReference() throws NamingException {
if (config instanceof Referenceable) {
Referenceable confref = (Referenceable)config;
if (reference == null) {
reference = new Reference(RepositoryImpl.class.getName(), RepositoryImpl.Factory.class.getName(), null);
// carry over all addresses from referenceable config
for (Enumeration en = confref.getReference().getAll(); en.hasMoreElements(); ) {
reference.add(en.nextElement());
}
// also add the information required by factory class
reference.add(new StringRefAddr(Factory.RCF, confref.getReference().getFactoryClassName()));
reference.add(new StringRefAddr(Factory.RCC, config.getClass().getName()));
}
return reference;
}
else {
throw new javax.naming.OperationNotSupportedException("Contained RepositoryConfig needs to implement javax.naming.Referenceable");
}
}
/**
* Implementation of {@link ObjectFactory} for repository instances.
*
* Works by creating a {@link Reference} to a {@link RepositoryConfig}
* instance based on the information obtained from the {@link RepositoryImpl}'s
* {@link Reference}.
*
* Address Types:
*
* - {@link #RCF}
*
- Class name for {@link ObjectFactory} creating instances of {@link RepositoryConfig}
* - {@link #RCC}
*
- Class name for {@link RepositoryConfig} instances
*
*
* All other types are copied over verbatim to the new {@link Reference}.
*
* A sample JNDI configuration inside a servlet container's server.xml
:
*
* <Resource
* name="jcr/repositoryname"
* auth="Container"
* type="org.apache.jackrabbit.jcr2spi.RepositoryImpl"
* factory="org.apache.jackrabbit.jcr2spi.RepositoryImpl$Factory"
* org.apache.jackrabbit.jcr2spi.RepositoryImpl.factory="class name of {@link ObjectFactory} for {@link RepositoryConfig} instances"
* org.apache.jackrabbit.jcr2spi.RepositoryImpl.class="class name of {@link RepositoryConfig} implementation class"
* ...additional properties passed to the {@link ObjectFactory}...
* />
*
*/
public static class Factory implements ObjectFactory {
public static final String RCF = RepositoryImpl.class.getName() + ".factory";
public static final String RCC = RepositoryImpl.class.getName() + ".class";
public Object getObjectInstance(Object obj, Name name, Context nameCtx, Hashtable,?> environment) throws Exception {
Object res = null;
if (obj instanceof Reference) {
Reference ref = (Reference)obj;
String classname = ref.getClassName();
if (RepositoryImpl.class.getName().equals(classname)) {
RefAddr rfac = ref.get(RCF);
if (rfac == null || !(rfac instanceof StringRefAddr)) {
throw new Exception("Address type " + RCF + " missing or of wrong class: " + rfac);
}
String configFactoryClassName = (String)((StringRefAddr)rfac).getContent();
RefAddr rclas = ref.get(RCC);
if (rclas == null || !(rclas instanceof StringRefAddr)) {
throw new Exception("Address type " + RCC + " missing or of wrong class: " + rclas);
}
String repositoryConfigClassName = (String)((StringRefAddr)rclas).getContent();
Object rof = Class.forName(configFactoryClassName).newInstance();
if (! (rof instanceof ObjectFactory)) {
throw new Exception(rof + " must implement ObjectFactory");
}
ObjectFactory of = (ObjectFactory)rof;
Reference newref = new Reference(repositoryConfigClassName,
configFactoryClassName, null);
// carry over all arguments except our own
for (Enumeration en = ref.getAll(); en.hasMoreElements(); ){
RefAddr ra = en.nextElement();
String type = ra.getType();
if (! RCF.equals(type) && ! RCC.equals(type)) {
newref.add(ra);
}
}
Object config = of.getObjectInstance(newref, name, nameCtx, environment);
if (! (config instanceof RepositoryConfig)) {
throw new Exception(config + " must implement RepositoryConfig");
}
return RepositoryImpl.create((RepositoryConfig)config);
}
else {
throw new Exception("Unexpected class: " + classname);
}
}
return res;
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy