org.apache.jackrabbit.jcr2spi.ItemManagerImpl 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 org.apache.jackrabbit.jcr2spi.hierarchy.HierarchyEntry;
import org.apache.jackrabbit.jcr2spi.hierarchy.HierarchyManager;
import org.apache.jackrabbit.jcr2spi.hierarchy.NodeEntry;
import org.apache.jackrabbit.jcr2spi.hierarchy.PropertyEntry;
import org.apache.jackrabbit.jcr2spi.state.ItemState;
import org.apache.jackrabbit.jcr2spi.state.ItemStateCreationListener;
import org.apache.jackrabbit.jcr2spi.state.NodeState;
import org.apache.jackrabbit.jcr2spi.state.PropertyState;
import org.apache.jackrabbit.jcr2spi.state.Status;
import org.apache.jackrabbit.jcr2spi.util.LogUtil;
import org.apache.jackrabbit.jcr2spi.version.VersionHistoryImpl;
import org.apache.jackrabbit.jcr2spi.version.VersionImpl;
import org.apache.jackrabbit.spi.Name;
import org.apache.jackrabbit.spi.Path;
import org.apache.jackrabbit.spi.commons.name.NameConstants;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.jcr.Item;
import javax.jcr.ItemNotFoundException;
import javax.jcr.Node;
import javax.jcr.NodeIterator;
import javax.jcr.PathNotFoundException;
import javax.jcr.Property;
import javax.jcr.PropertyIterator;
import javax.jcr.RepositoryException;
import javax.jcr.Workspace;
import java.util.Iterator;
/**
* ItemManagerImpl
implements the ItemManager
interface.
*/
public class ItemManagerImpl implements ItemManager, ItemStateCreationListener {
private static Logger log = LoggerFactory.getLogger(ItemManagerImpl.class);
private final SessionImpl session;
private final HierarchyManager hierMgr;
/**
* A cache for item instances created by this ItemManagerImpl
.
*
* The ItemState
s act as keys for the map. In contrast to
* o.a.j.core the item state are copied to transient space for reading and
* will therefor not change upon transient modifications.
*/
private final ItemCache itemCache;
/**
* Creates a new per-session instance ItemManagerImpl
instance.
*
* @param hierMgr HierarchyManager associated with the new instance
* @param session the session associated with the new instance
* @param cache the ItemCache to be used.
*/
ItemManagerImpl(HierarchyManager hierMgr, SessionImpl session, ItemCache cache) {
this.hierMgr = hierMgr;
this.session = session;
itemCache = cache;
// start listening to creation of ItemStates upon batch-reading in the
// workspace item state factory.
Workspace wsp = session.getWorkspace();
if (wsp instanceof WorkspaceImpl) {
((WorkspaceImpl) wsp).getItemStateFactory().addCreationListener(this);
}
}
//--------------------------------------------------------< ItemManager >---
/**
* @see ItemManager#dispose()
*/
public void dispose() {
// stop listening
Workspace wsp = session.getWorkspace();
if (wsp instanceof WorkspaceImpl) {
((WorkspaceImpl) wsp).getItemStateFactory().removeCreationListener(this);
}
// ... and clear the cache.
itemCache.clear();
}
/**
* @see ItemManager#nodeExists(Path)
*/
public boolean nodeExists(Path path) throws RepositoryException {
try {
// session-sanity & permissions are checked upon itemExists(ItemState)
NodeState nodeState = hierMgr.getNodeState(path);
return itemExists(nodeState);
} catch (PathNotFoundException pnfe) {
return false;
} catch (ItemNotFoundException infe) {
return false;
}
}
/**
* @see ItemManager#propertyExists(Path)
*/
public boolean propertyExists(Path path) throws RepositoryException {
try {
// session-sanity & permissions are checked upon itemExists(ItemState)
PropertyState propState = hierMgr.getPropertyState(path);
return itemExists(propState);
} catch (PathNotFoundException pnfe) {
return false;
} catch (ItemNotFoundException infe) {
return false;
}
}
/**
* @see ItemManager#itemExists(HierarchyEntry)
*/
public boolean itemExists(HierarchyEntry hierarchyEntry) throws RepositoryException {
try {
// session-sanity & permissions are checked upon itemExists(ItemState)
ItemState state = hierarchyEntry.getItemState();
return itemExists(state);
} catch (ItemNotFoundException e) {
return false;
}
}
/**
*
* @param itemState
* @return
*/
private boolean itemExists(ItemState itemState) {
try {
// check sanity of session
session.checkIsAlive();
// return true, if ItemState is valid. Access rights are granted,
// otherwise the state would not have been retrieved.
return itemState.isValid();
} catch (ItemNotFoundException infe) {
return false;
} catch (RepositoryException re) {
return false;
}
}
/**
* @see ItemManager#getNode(Path)
*/
public synchronized Node getNode(Path path) throws PathNotFoundException, RepositoryException {
NodeEntry nodeEntry = hierMgr.getNodeEntry(path);
try {
return (Node) getItem(nodeEntry);
} catch (ItemNotFoundException infe) {
throw new PathNotFoundException(LogUtil.safeGetJCRPath(path, session.getPathResolver()));
}
}
/**
* @see ItemManager#getProperty(Path)
*/
public synchronized Property getProperty(Path path) throws PathNotFoundException, RepositoryException {
PropertyEntry propertyEntry = hierMgr.getPropertyEntry(path);
try {
return (Property) getItem(propertyEntry);
} catch (ItemNotFoundException infe) {
throw new PathNotFoundException(LogUtil.safeGetJCRPath(path, session.getPathResolver()));
}
}
/**
* @see ItemManager#getItem(HierarchyEntry)
*/
public Item getItem(HierarchyEntry hierarchyEntry) throws ItemNotFoundException, RepositoryException {
session.checkIsAlive();
ItemState state = hierarchyEntry.getItemState();
if (!state.isValid()) {
throw new ItemNotFoundException(LogUtil.safeGetJCRPath(state, session.getPathResolver()));
}
// first try to access item from cache
Item item = itemCache.getItem(state);
// not yet in cache, need to create instance
if (item == null) {
// create instance of item
if (hierarchyEntry.denotesNode()) {
item = createNodeInstance((NodeState) state);
} else {
item = createPropertyInstance((PropertyState) state);
}
}
return item;
}
/**
* @see ItemManager#hasChildNodes(NodeEntry)
*/
public synchronized boolean hasChildNodes(NodeEntry parentEntry)
throws ItemNotFoundException, RepositoryException {
// check sanity of session
session.checkIsAlive();
Iterator iter = parentEntry.getNodeEntries();
while (iter.hasNext()) {
try {
// check read access by accessing the nodeState (implicit validation check)
NodeEntry entry = iter.next();
entry.getNodeState();
return true;
} catch (ItemNotFoundException e) {
// should not occur. ignore
log.debug("Failed to access node state.", e);
}
}
return false;
}
/**
* @see ItemManager#getChildNodes(NodeEntry)
*/
public synchronized NodeIterator getChildNodes(NodeEntry parentEntry)
throws ItemNotFoundException, RepositoryException {
// check sanity of session
session.checkIsAlive();
Iterator it = parentEntry.getNodeEntries();
return new LazyItemIterator(this, it);
}
/**
* @see ItemManager#hasChildProperties(NodeEntry)
*/
public synchronized boolean hasChildProperties(NodeEntry parentEntry)
throws ItemNotFoundException, RepositoryException {
// check sanity of session
session.checkIsAlive();
Iterator iter = parentEntry.getPropertyEntries();
while (iter.hasNext()) {
try {
PropertyEntry entry = iter.next();
// check read access by accessing the propState (also implicit validation).
entry.getPropertyState();
return true;
} catch (ItemNotFoundException e) {
// should not occur. ignore
log.debug("Failed to access node state.", e);
}
}
return false;
}
/**
* @see ItemManager#getChildProperties(NodeEntry)
*/
public synchronized PropertyIterator getChildProperties(NodeEntry parentEntry)
throws ItemNotFoundException, RepositoryException {
// check sanity of session
session.checkIsAlive();
Iterator propEntries = parentEntry.getPropertyEntries();
return new LazyItemIterator(this, propEntries);
}
//-------------------------------------------------------------< Object >---
/**
* Returns the the state of this instance in a human readable format.
*/
public String toString() {
StringBuilder builder = new StringBuilder();
builder.append("ItemManager (" + super.toString() + ")\n");
builder.append("Items in cache:\n");
builder.append(itemCache);
return builder.toString();
}
//----------------------------------------------------< private methods >---
/**
* @param state
* @return a new Node
instance.
* @throws RepositoryException
*/
private NodeImpl createNodeInstance(NodeState state) throws RepositoryException {
// we want to be informed on life cycle changes of the new node object
// in order to maintain item cache consistency
ItemLifeCycleListener[] listeners = new ItemLifeCycleListener[]{itemCache};
// check special nodes
Name ntName = state.getNodeTypeName();
if (NameConstants.NT_VERSION.equals(ntName)) {
// version
return new VersionImpl(session, state, listeners);
} else if (NameConstants.NT_VERSIONHISTORY.equals(ntName)) {
// version-history
return new VersionHistoryImpl(session, state, listeners);
} else {
// create common node object
return new NodeImpl(session, state, listeners);
}
}
/**
* @param state
* @return a new Property
instance.
*/
private PropertyImpl createPropertyInstance(PropertyState state) {
// we want to be informed on life cycle changes of the new property object
// in order to maintain item cache consistency
ItemLifeCycleListener[] listeners = new ItemLifeCycleListener[]{itemCache};
// create property object
PropertyImpl prop = new PropertyImpl(session, state, listeners);
return prop;
}
//------------------------------------------< ItemStateCreationListener >---
/**
*
* @param state
*/
public void created(ItemState state) {
if (state.isNode()) {
try {
createNodeInstance((NodeState) state);
} catch (RepositoryException e) {
// log warning and ignore
log.warn("Unable to create Node instance: " + e.getMessage());
}
} else {
createPropertyInstance((PropertyState) state);
}
}
public void statusChanged(ItemState state, int previousStatus) {
// stop listening if an state reached Status.REMOVED.
if (Status.REMOVED == state.getStatus()) {
state.removeListener(this);
}
// otherwise: nothing to do -> Item is listening to status changes and
// forces cleanup of cache entries through it's own status changes.
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy