/*
 * $Header: /home/cvspublic/jakarta-slide/src/webdav/server/org/apache/slide/webdav/util/properties/WorkspaceProperty.java,v 1.4 2005/01/10 18:09:22 luetzkendorf Exp $
 * $Revision: 1.4 $
 * $Date: 2005/01/10 18:09:22 $
 *
 * ====================================================================
 *
 * Copyright 1999-2002 The Apache Software Foundation 
 *
 * Licensed 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.slide.webdav.util.properties;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.apache.slide.common.NamespaceAccessToken;
import org.apache.slide.common.PropertyName;
import org.apache.slide.common.PropertyParseException;
import org.apache.slide.common.ServiceAccessException;
import org.apache.slide.common.SlideException;
import org.apache.slide.content.NodeProperty;
import org.apache.slide.content.NodeRevisionDescriptor;
import org.apache.slide.content.NodeRevisionDescriptors;
import org.apache.slide.content.RevisionDescriptorNotFoundException;
import org.apache.slide.event.VetoException;
import org.apache.slide.lock.ObjectLockedException;
import org.apache.slide.security.AccessDeniedException;
import org.apache.slide.store.Store;
import org.apache.slide.structure.LinkedObjectNotFoundException;
import org.apache.slide.structure.ObjectNotFoundException;
import org.apache.slide.util.Configuration;
import org.apache.slide.util.XMLValue;
import org.apache.slide.webdav.util.BindConstants;
import org.apache.slide.webdav.util.DeltavConstants;
import org.apache.slide.webdav.util.UriHandler;
import org.apache.slide.webdav.util.WebdavContext;
import org.apache.slide.webdav.util.resourcekind.ResourceKind;
import org.jdom.Element;
import org.jdom.JDOMException;

/**
 * Computes the DeltaV <code>workspace</code> property.
 * 
 * <p>Returns an XMLValue containing <code>&lt;href&gt;</code> elements
 * with the URI of the VCRs in the workspace identified the given
 * NodeRevisionDescriptor(s) that have a <code>&lt;checked-out&gt;</code>.
 * If the resource is not a Workspace, the returned XMLValue is empty.
 */
public class WorkspaceProperty extends AbstractComputedProperty
{
    public PropertyName getPropertyName() {
        return DeltavConstants.PN_WORKSPACE;
    }

    public Object computeValue(NamespaceAccessToken nsaToken,
            NodeRevisionDescriptors revisionDescriptors,
            NodeRevisionDescriptor revisionDescriptor, ResourceKind resourceKind, WebdavContext context)
            throws SlideException
    {
        Store store =  nsaToken.getUri(context.getSlideToken(), 
                revisionDescriptors.getUri()).getStore();
        if (Configuration.useBinding(store)) {
            return computeWithBinding(nsaToken, revisionDescriptors,
                    revisionDescriptor, context);
        } else {
            return computeWithoutBinding(nsaToken, revisionDescriptors,
                    revisionDescriptor, context);
        }
    }

    private Object computeWithoutBinding(NamespaceAccessToken nsaToken,
            NodeRevisionDescriptors revisionDescriptors,
            NodeRevisionDescriptor revisionDescriptor, WebdavContext context)
        throws PropertyParseException, ObjectNotFoundException,
            AccessDeniedException, LinkedObjectNotFoundException,
            ServiceAccessException, ObjectLockedException, VetoException,
            RevisionDescriptorNotFoundException, SlideException
    {
        XMLValue result = null;
        UriHandler hrUh = UriHandler.getUriHandler(revisionDescriptors,
                revisionDescriptor);
        String associatedWsUri = hrUh.getAssociatedWorkspaceUri();
        if (associatedWsUri != null) {
            result = new XMLValue();
            Element hrElm = new Element(DeltavConstants.E_HREF, DNSP);
            hrElm.setText(associatedWsUri);
            result.add(hrElm);
        }
        return result;
    }

    private Object computeWithBinding(NamespaceAccessToken nsaToken,
            NodeRevisionDescriptors revisionDescriptors,
            NodeRevisionDescriptor revisionDescriptor, WebdavContext context)
        throws PropertyParseException, ObjectNotFoundException,
            AccessDeniedException, LinkedObjectNotFoundException,
            ServiceAccessException, ObjectLockedException, VetoException,
            RevisionDescriptorNotFoundException, SlideException
    {
        XMLValue result = null;

        UriHandler rUh = UriHandler.getUriHandler(revisionDescriptors.getUri());
        if (rUh.getAssociatedWorkspaceUri() != null) {
            result = new XMLValue();
            Element hrElm = new Element(DeltavConstants.E_HREF, DNSP);
            hrElm.setText(rUh.getAssociatedWorkspaceUri());
            result.add(hrElm);
            return result;
        }

        NodeProperty psProp = revisionDescriptor
                .getProperty(BindConstants.PN_PARENT_SET);
        if (psProp == null) {
            return new XMLValue();
        }

        List psUris = new ArrayList();
        XMLValue xv;
        try {
            xv = new XMLValue(String.valueOf(psProp.getValue()));
        } catch (JDOMException e) {
            throw new PropertyParseException("Can't parse "
                    + BindConstants.PN_PARENT_SET);
        }
        Iterator i = xv.getList().iterator();
        while (i.hasNext()) {
            Element pElm = (Element) i.next();
            UriHandler hrUh = UriHandler.getUriHandler(pElm.getChild(
                    DeltavConstants.E_HREF, DNSP).getText());
            if (hrUh.getAssociatedWorkspaceUri() != null) {
                result = new XMLValue();
                Element hrElm = new Element(DeltavConstants.E_HREF, DNSP);
                hrElm.setText(hrUh.getAssociatedWorkspaceUri());
                result.add(hrElm);
                break;
            } else if (!hrUh.isRootUri()) {
                psUris.add(hrUh);
            }
        }

        if (result == null) {
            i = psUris.iterator();
            while (i.hasNext()) {
                NodeRevisionDescriptors nrds = nsaToken.getContentHelper()
                        .retrieve(context.getSlideToken(),
                                ((UriHandler) i.next()).getUri());
                NodeRevisionDescriptor nrd = nsaToken.getContentHelper()
                        .retrieve(context.getSlideToken(), nrds);
                result = (XMLValue) computeValue(nsaToken, nrds, nrd, null, context);
                if (result != null) {
                    break;
                }
            }
        }

        return result;
    }

}