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

import java.util.Arrays;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import javax.jcr.AccessDeniedException;
import javax.jcr.LoginException;
import javax.jcr.NamespaceException;
import javax.jcr.NamespaceRegistry;
import javax.jcr.NoSuchWorkspaceException;
import javax.jcr.RepositoryException;
import javax.jcr.UnsupportedRepositoryOperationException;
import javax.servlet.http.HttpSession;

import org.apache.avalon.framework.configuration.Configuration;
import org.apache.avalon.framework.configuration.ConfigurationException;
import org.apache.cocoon.components.ContextHelper;
import org.apache.cocoon.environment.ObjectModelHelper;
import org.apache.cocoon.environment.Request;
import org.apache.jackrabbit.core.nodetype.InvalidNodeTypeDefException;
import org.apache.jackrabbit.core.nodetype.NodeTypeManagerImpl;
import org.apache.jackrabbit.core.nodetype.NodeTypeRegistry;

/**
 * Lenya-specific repository implementation.
 */
public class LenyaRepository extends org.apache.cocoon.jcr.JackrabbitRepository {

    protected static final String CONTENT_NODE = "contentNode";

    protected static final String SESSION_ATTRIBUTE = javax.jcr.Session.class.getName();

    private Map namespaces = new HashMap();

    /**
     * @see org.apache.avalon.framework.configuration.Configurable#configure(org.apache.avalon.framework.configuration.Configuration)
     */
    public void configure(Configuration config) throws ConfigurationException {
        super.configure(config);

        Configuration[] namespaceConfigs = config.getChildren("namespace");
        for (int i = 0; i < namespaceConfigs.length; i++) {
            String prefix = namespaceConfigs[i].getAttribute("prefix");
            String uri = namespaceConfigs[i].getAttribute("uri");
            this.namespaces.put(prefix, uri);
        }
    }

    /**
     * @see javax.jcr.Repository#login()
     */
    public javax.jcr.Session login() throws LoginException, NoSuchWorkspaceException,
            RepositoryException {

        javax.jcr.Session jcrSession = null;

        Map objectModel = ContextHelper.getObjectModel(this.context);
        Request request = ObjectModelHelper.getRequest(objectModel);
        HttpSession session = request.getSession(false);
        if (session != null) {
            jcrSession = (javax.jcr.Session) session.getAttribute(SESSION_ATTRIBUTE);
            if (jcrSession == null) {
                jcrSession = super.login();
                session.setAttribute(SESSION_ATTRIBUTE, jcrSession);

                registerNamespaces(jcrSession);
                try {
                    registerNodeTypes(jcrSession);
                } catch (InvalidNodeTypeDefException e) {
                    throw new RepositoryException(e);
                }
            }
        }

        return jcrSession;
    }

    /**
     * Registers the Lenya-specific namespaces at the JCR workspace.
     * @param jcrSession The JCR session.
     * @throws RepositoryException if an error occurs.
     * @throws NamespaceException if an error occurs.
     * @throws UnsupportedRepositoryOperationException if an error occurs.
     * @throws AccessDeniedException if an error occurs.
     */
    protected void registerNamespaces(javax.jcr.Session jcrSession) throws RepositoryException,
            NamespaceException, UnsupportedRepositoryOperationException, AccessDeniedException {
        for (Iterator i = this.namespaces.keySet().iterator(); i.hasNext();) {
            String prefix = (String) i.next();
            String uri = (String) this.namespaces.get(prefix);
            NamespaceRegistry registry = jcrSession.getWorkspace().getNamespaceRegistry();
            if (!Arrays.asList(registry.getPrefixes()).contains(prefix)) {
                registry.registerNamespace(prefix, uri);
            }
        }
    }

    protected void registerNodeTypes(javax.jcr.Session jcrSession) throws RepositoryException,
            InvalidNodeTypeDefException {

        NodeTypeManagerImpl nodeTypeManager = (NodeTypeManagerImpl) jcrSession.getWorkspace()
                .getNodeTypeManager();
        NodeTypeRegistry registry = nodeTypeManager.getNodeTypeRegistry();
        /*
        if (!registry.isRegistered(new QName(LenyaMetaData.NAMESPACE, CONTENT_NODE))) {
            
            List propDefs = new ArrayList();
            Map key2namespace = new HashMap();

            String[] lenyaKeys = LenyaMetaData.ELEMENTS;
            for (int i = 0; i < lenyaKeys.length; i++) {
                key2namespace.put(lenyaKeys[i], LenyaMetaData.NAMESPACE);
            }

            List dcKeyList = DublinCoreImpl.getAttributeNames();
            String[] dcKeys = (String[]) dcKeyList.toArray(new String[dcKeyList.size()]);
            for (int i = 0; i < dcKeys.length; i++) {
                key2namespace.put(dcKeys[i], DublinCore.DC_NAMESPACE);
            }

            NodeTypeDef def = new NodeTypeDef();
            def.setMixin(true);
            def.setName(new QName(LenyaMetaData.NAMESPACE, CONTENT_NODE));

            for (Iterator i = key2namespace.keySet().iterator(); i.hasNext();) {
                String key = (String) i.next();
                String namespace = (String) key2namespace.get(key);
                PropDefImpl propDef = new PropDefImpl();
                propDef.setDeclaringNodeType(def.getName());
                propDef.setName(new QName(namespace, key));
                propDef.setMandatory(false);
                propDef.setRequiredType(PropertyType.STRING);
                propDef.setMultiple(true);
                propDefs.add(propDef);
            }

            def.setPropertyDefs((PropDef[]) propDefs.toArray(new PropDef[propDefs.size()]));

            registry.registerNodeType(def);
        }
        */
    }

}
