Package org.apache.slide.store

Source Code of org.apache.slide.store.ParentStore

/*
* $Header: /home/cvs/jakarta-slide/src/share/org/apache/slide/store/ParentStore.java,v 1.3.2.1 2004/02/05 16:05:12 mholz Exp $
* $Revision: 1.3.2.1 $
* $Date: 2004/02/05 16:05:12 $
*
* ====================================================================
*
* 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.store;


import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
import java.util.Vector;
import javax.transaction.xa.XAException;
import javax.transaction.xa.Xid;
import org.apache.slide.common.NamespaceAccessToken;
import org.apache.slide.common.ServiceAccessException;
import org.apache.slide.common.ServiceInitializationFailedException;
import org.apache.slide.common.Uri;
import org.apache.slide.common.UriPath;
import org.apache.slide.content.NodeProperty;
import org.apache.slide.content.NodeRevisionContent;
import org.apache.slide.content.NodeRevisionDescriptor;
import org.apache.slide.content.NodeRevisionDescriptors;
import org.apache.slide.content.NodeRevisionNumber;
import org.apache.slide.content.RevisionAlreadyExistException;
import org.apache.slide.content.RevisionDescriptorNotFoundException;
import org.apache.slide.content.RevisionNotFoundException;
import org.apache.slide.lock.LockTokenNotFoundException;
import org.apache.slide.lock.NodeLock;
import org.apache.slide.macro.ConflictException;
import org.apache.slide.store.tlock.TLock;
import org.apache.slide.store.tlock.TLockManager;
import org.apache.slide.store.tlock.TLockedException;
import org.apache.slide.security.NodePermission;
import org.apache.slide.store.ExtendedStore;
import org.apache.slide.store.NodeStore;
import org.apache.slide.structure.ObjectAlreadyExistsException;
import org.apache.slide.structure.ObjectNode;
import org.apache.slide.structure.ObjectNotFoundException;
import org.apache.slide.util.Configuration;
import org.apache.slide.util.XMLValue;
import org.jdom.Element;

/**
* Store implementation supporting binding-resolution and t-locking.
* By extending ExtendedStore, this store implementation inherits also
* caching.
*
* @author    michael.hartmeier@softwareag.com
* @author    peter.nevermann@softwareag.com
* @version   $Revision: 1.3.2.1 $
*/
public class ParentStore extends /*AbstractStore*/ ExtendedStore {
   
    private static final int TLOCK_TIMEOUT = 5000; // TODO
    private static TLockManager tlockManager = new TLockManager(TLOCK_TIMEOUT);
   
    // overwrites inherited
    public void initialize(NamespaceAccessToken token)
        throws ServiceInitializationFailedException {
       
        super.initialize(token);
    }
   
    // overwrites inherited
    public void commit(Xid xid, boolean onePhase) throws XAException {
        try {
            super.commit(xid, onePhase);
        }
        finally {
            tlockManager.releaseLocks();
        }
    }
   
    // overwrites inherited
    public void rollback(Xid xid) throws XAException {
        try {
            super.rollback(xid);
        }
        finally {
            tlockManager.releaseLocks();
        }
    }
   
    // overwrites inherited
    public ObjectNode retrieveObject(Uri uri)
        throws ServiceAccessException, ObjectNotFoundException {
       
        return doRetrieveObjectNode(uri);
    }
   
    // overwrites inherited
    public void storeObject(Uri uri, ObjectNode object)
        throws ServiceAccessException, ObjectNotFoundException {
       
        ResourceId resourceId = obtainResourceId(uri);
        ObjectNode objectClone = object.cloneObject();
        objectClone.setUri(resourceId.getUuri()); // switch to uuri
        try {
            tlockManager.lock(resourceId, uri.toString(), TLock.WRITE_LOCK);
        } catch (TLockedException e) {
            throw new ServiceAccessException(this, new ConflictException(uri.toString()));
        }
        super.storeObject(resourceId, objectClone);
    }
   
    // overwrites inherited
    public void createObject(Uri uri, ObjectNode object)
        throws ServiceAccessException, ObjectAlreadyExistsException {
       
        ResourceId resourceId = ResourceId.createNew(uri);
        object.setUuri(resourceId.getUuri());
        ObjectNode objectClone = object.cloneObject();
        objectClone.setUri(resourceId.getUuri()); // switch to uuri
        tlockManager.create(TLock.WRITE_LOCK, uri.toString(), resourceId);
        cacheResolve(uri, resourceId);
        super.createObject(resourceId, objectClone);
    }
   
    // overwrites inherited
    public void removeObject(Uri uri, ObjectNode object)
        throws ServiceAccessException, ObjectNotFoundException {
       
        ResourceId resourceId = obtainResourceId(uri);
        ObjectNode objectClone = object.cloneObject();
        objectClone.setUri(resourceId.getUuri()); // switch to uuri
        try {
            tlockManager.lock(resourceId, uri.toString(), TLock.WRITE_LOCK);
        } catch (TLockedException e) {
            throw new ServiceAccessException(this, new ConflictException(uri.toString()));
        }
        super.removeObject(resourceId, objectClone);
    }
   
    // overwrites inherited
    public void grantPermission(Uri uri, NodePermission permission)
        throws ServiceAccessException {
       
        try {
            ResourceId resourceId = obtainResourceId(uri);
            NodePermission permissionClone = permission.cloneObject();
            permissionClone.setObject(resourceId.getUuri()); // switch to uuri
            super.grantPermission(resourceId, permissionClone);
        }
        catch (ObjectNotFoundException e) {
            throw new ServiceAccessException(this, e);
        }
    }
   
    // overwrites inherited
    public void revokePermission(Uri uri, NodePermission permission)
        throws ServiceAccessException {
       
        try {
            ResourceId resourceId = obtainResourceId(uri);
            NodePermission permissionClone = permission.cloneObject();
            permissionClone.setObject(resourceId.getUuri()); // switch to uuri
            super.revokePermission(resourceId, permissionClone);
        }
        catch (ObjectNotFoundException e) {
            throw new ServiceAccessException(this, e);
        }
    }
   
    // overwrites inherited
    public void revokePermissions(Uri uri)
        throws ServiceAccessException {
       
        try {
            super.revokePermissions(obtainResourceId(uri));
        }
        catch (ObjectNotFoundException e) {
            throw new ServiceAccessException(this, e);
        }
    }
   
    // overwrites inherited
    public Enumeration enumeratePermissions(Uri uri)
        throws ServiceAccessException {
       
        try {
            Enumeration permissions = super.enumeratePermissions(obtainResourceId(uri));
            Vector result = new Vector();
            while (permissions.hasMoreElements()) {
                NodePermission p = ((NodePermission)permissions.nextElement()).cloneObject();
                p.setObject(uri.toString()); // switch to uri
                result.add(p);
            }
            return result.elements();
        }
        catch (ObjectNotFoundException e) {
            throw new ServiceAccessException(this, e);
        }
    }
   
    // overwrites inherited
    public void putLock(Uri uri, NodeLock lock)
        throws ServiceAccessException {
       
        try {
            ResourceId resourceId = obtainResourceId(uri);
            NodeLock lockClone = lock.cloneObject();
            lockClone.setObjectUri(resourceId.getUuri()); // switch to uuri
            super.putLock(resourceId, lockClone);
        }
        catch (ObjectNotFoundException e) {
            throw new ServiceAccessException(this, e);
        }
    }
   
    // overwrites inherited
    public void renewLock(Uri uri, NodeLock lock)
        throws ServiceAccessException, LockTokenNotFoundException {
       
        try {
            ResourceId resourceId = obtainResourceId(uri);
            NodeLock lockClone = lock.cloneObject();
            lockClone.setObjectUri(resourceId.getUuri()); // switch to uuri
            super.renewLock(resourceId, lockClone);
        }
        catch (ObjectNotFoundException e) {
            throw new ServiceAccessException(this, e);
        }
    }
   
    // overwrites inherited
    public void removeLock(Uri uri, NodeLock lock)
        throws ServiceAccessException, LockTokenNotFoundException {
       
        try {
            ResourceId resourceId = obtainResourceId(uri);
            NodeLock lockClone = lock.cloneObject();
            lockClone.setObjectUri(resourceId.getUuri()); // switch to uuri
            super.removeLock(resourceId, lockClone);
        }
        catch (ObjectNotFoundException e) {
            throw new ServiceAccessException(this, e);
        }
    }
   
    // overwrites inherited
    public void killLock(Uri uri, NodeLock lock)
        throws ServiceAccessException, LockTokenNotFoundException {
       
        try {
            ResourceId resourceId = obtainResourceId(uri);
            NodeLock lockClone = lock.cloneObject();
            lockClone.setObjectUri(resourceId.getUuri()); // switch to uuri
            super.killLock(resourceId, lockClone);
        }
        catch (ObjectNotFoundException e) {
            throw new ServiceAccessException(this, e);
        }
    }
   
    // overwrites inherited
    public Enumeration enumerateLocks(Uri uri)
        throws ServiceAccessException {
       
        try {
            Enumeration locks = super.enumerateLocks(obtainResourceId(uri));
            Vector result = new Vector();
            while (locks.hasMoreElements()) {
                NodeLock l = ((NodeLock)locks.nextElement()).cloneObject();
                l.setObjectUri(uri.toString()); // switch to uri
                result.add(l);
            }
            return result.elements();
        }
        catch (ObjectNotFoundException e) {
            throw new ServiceAccessException(this, e);
        }
    }
   
    // overwrites inherited
    public NodeRevisionDescriptors retrieveRevisionDescriptors(Uri uri)
        throws ServiceAccessException, RevisionDescriptorNotFoundException {
       
        try {
            NodeRevisionDescriptors nrdsClone =
                super.retrieveRevisionDescriptors(obtainResourceId(uri)).cloneObject();
            nrdsClone.setUri(uri.toString());
            return nrdsClone;
        }
        catch (ObjectNotFoundException e) {
            // TODO: throw RevisionDescriptorsNotFoundException???
            throw new ServiceAccessException(this, e);
        }
    }
   
    // overwrites inherited
    public void createRevisionDescriptors
        (Uri uri, NodeRevisionDescriptors revisionDescriptors)
        throws ServiceAccessException {
       
        try {
            ResourceId resourceId = obtainResourceId(uri);
            NodeRevisionDescriptors nrdsClone = revisionDescriptors.cloneObject();
            nrdsClone.setUri(resourceId.getUuri()); // switch to uuri
            super.createRevisionDescriptors(resourceId, nrdsClone);
        }
        catch (ObjectNotFoundException e) {
            throw new ServiceAccessException(this, e);
        }
    }
   
    // overwrites inherited
    public void storeRevisionDescriptors
        (Uri uri, NodeRevisionDescriptors revisionDescriptors)
        throws ServiceAccessException, RevisionDescriptorNotFoundException {
       
        try {
            ResourceId resourceId = obtainResourceId(uri);
            NodeRevisionDescriptors nrdsClone = revisionDescriptors.cloneObject();
            nrdsClone.setUri(resourceId.getUuri()); // switch to uuri
            super.storeRevisionDescriptors(resourceId, nrdsClone);
        }
        catch (ObjectNotFoundException e) {
            // TODO: throw RevisionDescriptorsNotFoundException???
            throw new ServiceAccessException(this, e);
        }
    }
   
    // overwrites inherited
    public void removeRevisionDescriptors(Uri uri)
        throws ServiceAccessException {
       
        try {
            super.removeRevisionDescriptors(obtainResourceId(uri));
        }
        catch (ObjectNotFoundException e) {
            throw new ServiceAccessException(this, e);
        }
    }
   
    // overwrites inherited
    public NodeRevisionDescriptor retrieveRevisionDescriptor
        (Uri uri, NodeRevisionNumber revisionNumber)
        throws ServiceAccessException, RevisionDescriptorNotFoundException {
       
        try {
            ObjectNode objectNode = doRetrieveObjectNode(uri);
            ResourceId resourceId = obtainResourceId(uri);
            NodeRevisionDescriptor nrd = super.retrieveRevisionDescriptor(resourceId, revisionNumber);
            nrd.setProperty("resource-id", resourceId.asXml());
            nrd.setProperty("parent-set", getXmlParentSet(uri, objectNode));
            return nrd;
        }
        catch (ObjectNotFoundException e) {
            // TODO: throw RevisionDescriptorNotFoundException???
            throw new ServiceAccessException(this, e);
        }
    }
    public String getXmlParentSet(Uri uri, ObjectNode objectNode) throws ServiceAccessException, ObjectNotFoundException {
        ResourceId resourceId = obtainResourceId(uri);
        // if objectNode is the root of a store, parent-uuri.equals(""),
        // thus we cannot call getOneParentUri because
        // we cannot resolve the uuri
        boolean useBinding = Configuration.useBinding(this) && !resourceId.isStoreRoot();
       
        XMLValue result = new XMLValue();
        Enumeration parentBindings = objectNode.enumerateParentBindings();
        while (parentBindings.hasMoreElements()) {
            ObjectNode.Binding parentBinding = (ObjectNode.Binding) parentBindings.nextElement();
            Element parentElm = new Element("parent", NodeProperty.NamespaceCache.DEFAULT_NAMESPACE);
            Element hrefElm = new Element("href", NodeProperty.NamespaceCache.DEFAULT_NAMESPACE);
            String parentUriStr = new UriPath(objectNode.getUri()).parent().toString();
            Uri parentUri = new Uri(uri.getToken(), uri.getNamespace(), parentUriStr);
            String uriStr;
            if (useBinding) {
                ResourceId parentResourceId = ResourceId.create(parentUri, parentBinding.getUuri());
                uriStr = getOneUri(parentResourceId);
            }
            else {
                uriStr = parentUriStr;
            }
            hrefElm.setText(uriStr);
            parentElm.addContent(hrefElm);
            Element segmentElm = new Element("segment", NodeProperty.NamespaceCache.DEFAULT_NAMESPACE);
            segmentElm.setText(parentBinding.getName());
            parentElm.addContent(segmentElm);
            result.add(parentElm);
        }
       
        return result.toString();
    }
   
    private String getOneUri(ResourceId resourceId) throws ServiceAccessException, ObjectNotFoundException {
        String result = "";
        while (!resourceId.isStoreRoot()) {
            ObjectNode objectNode = super.retrieveObject(resourceId);
            Enumeration enum = objectNode.enumerateParentBindings();
            if (!enum.hasMoreElements()) {
                throw new IllegalStateException();
            }
            ObjectNode.Binding parentBinding = (ObjectNode.Binding) enum.nextElement();
            String parentSegment = parentBinding.getName();
            result = "/" + parentSegment + result;
            resourceId = ResourceId.create(resourceId, parentBinding.getUuri());
        }
        return "/".equals(resourceId.getScope().toString())
            ? result
            : resourceId.getScope()+result;
    }
   
    // overwrites inherited
    public void createRevisionDescriptor
        (Uri uri, NodeRevisionDescriptor revisionDescriptor)
        throws ServiceAccessException {
       
        try {
            revisionDescriptor.removeProperty("resource-id");
            revisionDescriptor.removeProperty("parent-set");
            super.createRevisionDescriptor(obtainResourceId(uri), revisionDescriptor);
        }
        catch (ObjectNotFoundException e) {
            throw new ServiceAccessException(this, e);
        }
    }
   
    // overwrites inherited
    public void storeRevisionDescriptor
        (Uri uri, NodeRevisionDescriptor revisionDescriptor)
        throws ServiceAccessException, RevisionDescriptorNotFoundException {
       
        try {
            revisionDescriptor.removeProperty("resource-id");
            revisionDescriptor.removeProperty("parent-set");
            super.storeRevisionDescriptor(obtainResourceId(uri), revisionDescriptor);
        }
        catch (ObjectNotFoundException e) {
            // TODO: throw RevisionDescriptorNotFoundException???
            throw new ServiceAccessException(this, e);
        }
    }
   
    // overwrites inherited
    public void removeRevisionDescriptor(Uri uri, NodeRevisionNumber number)
        throws ServiceAccessException {
       
        try {
            super.removeRevisionDescriptor(obtainResourceId(uri), number);
        }
        catch (ObjectNotFoundException e) {
            throw new ServiceAccessException(this, e);
        }
    }
   
    // overwrites inherited
    public NodeRevisionContent retrieveRevisionContent
        (Uri uri, NodeRevisionDescriptor revisionDescriptor)
        throws ServiceAccessException, RevisionNotFoundException {
       
        try {
            // TODO: throw RevisionNotFoundException???
            return super.retrieveRevisionContent(obtainResourceId(uri), revisionDescriptor);
        }
        catch (ObjectNotFoundException e) {
            throw new ServiceAccessException(this, e);
        }
    }
   
    // overwrites inherited
    public void createRevisionContent
        (Uri uri, NodeRevisionDescriptor revisionDescriptor,
         NodeRevisionContent revisionContent)
        throws ServiceAccessException, RevisionAlreadyExistException {
       
        try {
            super.createRevisionContent(obtainResourceId(uri), revisionDescriptor, revisionContent);
        }
        catch (ObjectNotFoundException e) {
            throw new ServiceAccessException(this, e);
        }
    }
   
    // overwrites inherited
    public void storeRevisionContent
        (Uri uri, NodeRevisionDescriptor revisionDescriptor,
         NodeRevisionContent revisionContent)
        throws ServiceAccessException, RevisionNotFoundException {
       
        try {
            // TODO: throw RevisionNotFoundException???
            super.storeRevisionContent(obtainResourceId(uri), revisionDescriptor, revisionContent);
        }
        catch (ObjectNotFoundException e) {
            throw new ServiceAccessException(this, e);
        }
    }
   
    // overwrites inherited
    public void removeRevisionContent
        (Uri uri, NodeRevisionDescriptor revisionDescriptor)
        throws ServiceAccessException {
       
        try {
            super.removeRevisionContent(obtainResourceId(uri), revisionDescriptor);
        }
        catch (ObjectNotFoundException e) {
            throw new ServiceAccessException(this, e);
        }
    }
   
    // ================================================================
   
    /**
     * NodeStore accessor
     */
    public NodeStore getNodeStore() {
        return nodeStore;
    }
   
    /**
     * Always returns false. Default implementation for this method
     * Stores that support binding should override this method.
     */
    public boolean useBinding() {
        return "true".equalsIgnoreCase((String)getParameter("useBinding"));
    }
   
    /**
     * Worker method to retrieve the ObjectNode. Resolve if binding is enabled.
     *
     * @param    uri                 an Uri
     * @return   an ObjectNode
     * @throws   ServiceAccessException
     * @throws   ObjectNotFoundException
     */
    private ObjectNode doRetrieveObjectNode( Uri uri ) throws ServiceAccessException, ObjectNotFoundException {
        try {
            if (isForceStoreEnlistment(uri)) {
                return doRetrieveObjectNode( uri, TLock.WRITE_LOCK, TLock.READ_LOCK);
            } else {
                // we cannot be sure there's a transaction. Locks could get lost
                // if there's no commit
                return doRetrieveObjectNode( uri, TLock.NO_LOCK, TLock.NO_LOCK);
            }
        }
        catch (TLockedException e) {
            throw new ServiceAccessException(this, new ConflictException(uri.toString()));
        }
    }
   
    private ObjectNode doRetrieveObjectNode(Uri uri, int lockType, int parentLockType)
        throws TLockedException, ServiceAccessException, ObjectNotFoundException  {
       
        ObjectNode result;
        synchronized (tlockManager) {
            if (Configuration.useBinding(this)) {
                result = doResolve(uri, lockType, parentLockType);
                result.setUuri(result.getUri());
                result.setUri(uri.toString()); // switch to uri
            } else {
                ResourceId resourceId = ResourceId.create(uri, uri.toString());
                tlockManager.lock(resourceId, uri.toString(), lockType);
                // call super such that e.g. caching can take place
                result = super.retrieveObject(uri);
                result.setUuri(result.getUri());
            }
        }
        return result;
    }
   
    /**
     * Worker method that actually resolves the uri.
     */
    private ObjectNode doResolve(Uri uri, int lockType, int parentLockType) throws TLockedException, ObjectNotFoundException, ServiceAccessException {
        // check resolve cache first
        ResourceId resourceId = checkResolveCache(uri);
       
        if (resourceId == null) {
            UriPath uriPath = new UriPath(uri.toString());
            String[] segments = uriPath.tokens();
            String rootUriStr = uri.getScope().toString();
            String currentUriStr = rootUriStr;
            Uri currentUri = new Uri(uri.getToken(), uri.getNamespace(), currentUriStr);
            ResourceId currentResourceId = ResourceId.create(currentUri, currentUriStr);
            int start = new UriPath(rootUriStr).tokens().length;

            for (int i = start; i < segments.length; i++) {
                tlockManager.lock(currentResourceId, currentUriStr, parentLockType);
                // cacheResolve(currentUri, currentResourceId);
                // TODO: make it work with caching here :-(
               
                // call super such that e.g. caching can take place
                ObjectNode objectNode = super.retrieveObject(currentResourceId);
                currentUriStr = uriPath.subUriPath(0, i + 1).toString();
                currentUri = new Uri(uri.getToken(), uri.getNamespace(), currentUriStr);
                String currentUuri = objectNode.getBindingUuri(segments[i]);
                if (currentUuri == null) {
                    throw new ObjectNotFoundException(currentUriStr);
                }
                currentResourceId = ResourceId.create(currentUri, currentUuri);
            }
            resourceId = currentResourceId;

            // cache resolve result
            // cacheResolve(uri, resourceId);
            // TODO: make it work with caching here :-(
        }
        // else {
        //     doTLock(uri, resourceId, lockType, parentLockType);
        // }
        // TODO: make it work with caching here :-(
       
        tlockManager.lock(resourceId, uri.toString(), lockType);
        // call super such that e.g. caching can take place
        return super.retrieveObject(resourceId);
    }
   
    private void doTLock(Uri uri, ResourceId resourceId, int lockType, int parentLockType) throws TLockedException, ObjectNotFoundException, ServiceAccessException {
        UriPath uriPath = new UriPath(uri.toString());
        String[] segments = uriPath.tokens();
        int start = new UriPath(uri.getScope().toString()).tokens().length;
       
        for (int i = start; i < segments.length; i++) {
            String currentUriStr = uriPath.subUriPath(0, i).toString();
            Uri currentUri = new Uri(uri.getToken(), uri.getNamespace(), currentUriStr);
//            ResourceId currentResourceId = obtainResourceId(currentUri);
            ResourceId currentResourceId = checkResolveCache(currentUri);
            if (currentResourceId == null) {
                currentResourceId = obtainResourceId(currentUri);
            }
            tlockManager.lock(currentResourceId, currentUriStr, parentLockType);
        }
       
        tlockManager.lock(resourceId, uri.toString(), lockType);
    }
   
    private void cacheResolve(Uri uri, ResourceId resourceId) {
        if (uri.getToken() != null) {
            uri.getToken().cacheResolve(uri, resourceId);
//            System.out.println("@@@ >>> "+uri+"->"+resourceId);
        }
    }
   
    private ResourceId checkResolveCache(Uri uri) {
        ResourceId resourceId = null;
        if (uri.getToken() != null) {
            resourceId = uri.getToken().checkResolveCache(uri);
        }
        return resourceId;
    }
   
    private ResourceId obtainResourceId(Uri uri) throws ServiceAccessException, ObjectNotFoundException {
        ObjectNode objectNode = doRetrieveObjectNode(uri);
        ResourceId resourceId = ResourceId.create(uri, objectNode.getUuri());
        return resourceId;
    }
}

TOP

Related Classes of org.apache.slide.store.ParentStore

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.