All Downloads are FREE. Search and download functionalities are using the official Maven repository.

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