Package org.apache.jackrabbit.jcr2spi

Source Code of org.apache.jackrabbit.jcr2spi.RepositoryImpl$Factory

/*
* 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 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.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;

/**
* <code>RepositoryImpl</code>...
*/
public class RepositoryImpl extends AbstractRepository implements Referenceable {

    // 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;
        descriptors = config.getRepositoryService().getRepositoryDescriptors();
    }

    public static Repository create(RepositoryConfig config) throws RepositoryException {
        return new RepositoryImpl(config);
    }

    //---------------------------------------------------------< Repository >---
    /**
     * @see Repository#getDescriptorKeys()
     */
    public String[] getDescriptorKeys() {
        String[] keys = (String[]) descriptors.keySet().toArray(new String[descriptors.keySet().size()]);
        return keys;
    }

    /**
     * @see Repository#getDescriptor(String)
     */
    public String getDescriptor(String descriptorKey) {
        return (String) descriptors.get(descriptorKey);
    }

    /**
     * @see Repository#login(javax.jcr.Credentials, String)
     */
    public Session login(Credentials credentials, String workspaceName) throws LoginException, NoSuchWorkspaceException, RepositoryException {
        String wspName = (workspaceName == null) ? config.getDefaultWorkspaceName() : workspaceName;
        SessionInfo info = config.getRepositoryService().obtain(credentials, wspName);
        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;
        }
    }

    //---------------------------------------------------------< Rereferencable >---

    /**
     * @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((RefAddr)(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.
     * <p>
     * Works by creating a {@link Reference} to a {@link RepositoryConfig}
     * instance based on the information obtained from the {@link RepositoryImpl}'s
     * {@link Reference}.
     * <p>
     * Address Types:
     * <dl>
     <dt>{@link #RCF}
     <dd>Class name for {@link ObjectFactory} creating instances of {@link RepositoryConfig}</dd>
     <dt>{@link #RCC}
     <dd>Class name for {@link RepositoryConfig} instances</dd>
     * </dl>
     * <p>
     * All other types are copied over verbatim to the new {@link Reference}.
     * <p>
     * A sample JNDI configuration inside a servlet container's <code>server.xml</code>:
     * <pre>
     *   &lt;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="<em>class name of {@link ObjectFactory} for {@link RepositoryConfig} instances</em>"
     *         org.apache.jackrabbit.jcr2spi.RepositoryImpl.class="<em>class name of {@link RepositoryConfig} implementation class</em>"
     *         <em>...additional properties passed to the {@link ObjectFactory}...</em>
     *   /&gt;
     * </pre>
     */
    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 = (RefAddr)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;
        }
    }
}
TOP

Related Classes of org.apache.jackrabbit.jcr2spi.RepositoryImpl$Factory

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.