| /* |
| * 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.sling.testing.mock.jcr; |
| |
| import java.io.InputStream; |
| import java.math.BigDecimal; |
| import java.util.Calendar; |
| import java.util.regex.Pattern; |
| |
| import javax.jcr.Binary; |
| import javax.jcr.Item; |
| import javax.jcr.ItemNotFoundException; |
| import javax.jcr.Node; |
| import javax.jcr.NodeIterator; |
| import javax.jcr.Property; |
| import javax.jcr.PropertyIterator; |
| import javax.jcr.RangeIterator; |
| import javax.jcr.RepositoryException; |
| import javax.jcr.Session; |
| import javax.jcr.Value; |
| import javax.jcr.lock.Lock; |
| import javax.jcr.nodetype.NodeDefinition; |
| import javax.jcr.nodetype.NodeType; |
| import javax.jcr.version.Version; |
| import javax.jcr.version.VersionHistory; |
| |
| import org.apache.commons.lang3.StringUtils; |
| import org.apache.jackrabbit.JcrConstants; |
| import org.apache.jackrabbit.commons.ItemNameMatcher; |
| import org.apache.jackrabbit.commons.iterator.NodeIteratorAdapter; |
| import org.apache.jackrabbit.commons.iterator.PropertyIteratorAdapter; |
| |
| /** |
| * Mock {@link Node} implementation |
| */ |
| class MockNode extends AbstractItem implements Node { |
| |
| public MockNode(final ItemData itemData, final Session session) { |
| super(itemData, session); |
| } |
| |
| @Override |
| public Node addNode(final String relPath) throws RepositoryException { |
| return addNode(relPath, JcrConstants.NT_UNSTRUCTURED); |
| } |
| |
| @Override |
| public Node addNode(final String relPath, final String primaryNodeTypeName) throws RepositoryException { |
| String path = makeAbsolutePath(relPath); |
| ItemData itemData = ItemData.newNode(path, new MockNodeType(primaryNodeTypeName)); |
| Node node = new MockNode(itemData, getSession()); |
| getMockedSession().addItem(itemData); |
| node.setProperty(JcrConstants.JCR_PRIMARYTYPE, primaryNodeTypeName); |
| |
| // special handling for some node types |
| if (StringUtils.equals(primaryNodeTypeName, JcrConstants.NT_FILE)) { |
| node.setProperty(JcrConstants.JCR_CREATED, Calendar.getInstance()); |
| node.setProperty("jcr:createdBy", getMockedSession().getUserID()); |
| } |
| |
| return node; |
| } |
| |
| @Override |
| public Node getNode(final String relPath) throws RepositoryException { |
| String path = makeAbsolutePath(relPath); |
| return getSession().getNode(path); |
| } |
| |
| @Override |
| public NodeIterator getNodes() throws RepositoryException { |
| RangeIterator items = getMockedSession().listChildren(getPath(), new ItemFilter() { |
| @Override |
| public boolean accept(final ItemData item) throws RepositoryException { |
| return item.isNode(); |
| } |
| }); |
| return new NodeIteratorAdapter(items, items.getSize()); |
| } |
| |
| @Override |
| public NodeIterator getNodes(final String namePattern) throws RepositoryException { |
| final Pattern pattern = Pattern.compile(namePattern); |
| RangeIterator items = getMockedSession().listChildren(getPath(), new ItemFilter() { |
| @Override |
| public boolean accept(final ItemData item) throws RepositoryException { |
| return item.isNode() && pattern.matcher(item.getName()).matches(); |
| } |
| }); |
| return new NodeIteratorAdapter(items, items.getSize()); |
| } |
| |
| @Override |
| public NodeIterator getNodes(final String[] nameGlobs) throws RepositoryException { |
| RangeIterator items = getMockedSession().listChildren(getPath(), new ItemFilter() { |
| @Override |
| public boolean accept(final ItemData item) throws RepositoryException { |
| return item.isNode() && ItemNameMatcher.matches(item.getName(), nameGlobs); |
| } |
| }); |
| return new NodeIteratorAdapter(items, items.getSize()); |
| } |
| |
| |
| @Override |
| public PropertyIterator getProperties() throws RepositoryException { |
| RangeIterator items = getMockedSession().listChildren(getPath(), new ItemFilter() { |
| @Override |
| public boolean accept(final ItemData item) throws RepositoryException { |
| return item.isProperty(); |
| } |
| }); |
| return new PropertyIteratorAdapter(items, items.getSize()); |
| } |
| |
| @Override |
| public PropertyIterator getProperties(final String namePattern) throws RepositoryException { |
| final Pattern pattern = Pattern.compile(namePattern); |
| RangeIterator items = getMockedSession().listChildren(getPath(), new ItemFilter() { |
| @Override |
| public boolean accept(final ItemData item) throws RepositoryException { |
| return item.isProperty() && pattern.matcher(item.getName()).matches(); |
| } |
| }); |
| return new PropertyIteratorAdapter(items, items.getSize()); |
| } |
| |
| @Override |
| public PropertyIterator getProperties(final String[] nameGlobs) throws RepositoryException { |
| RangeIterator items = getMockedSession().listChildren(getPath(), new ItemFilter() { |
| @Override |
| public boolean accept(final ItemData item) throws RepositoryException { |
| return item.isProperty() && ItemNameMatcher.matches(item.getName(), nameGlobs); |
| } |
| }); |
| return new PropertyIteratorAdapter(items, items.getSize()); |
| } |
| |
| @Override |
| public Property getProperty(final String relPath) throws RepositoryException { |
| String path = makeAbsolutePath(relPath); |
| return getSession().getProperty(path); |
| } |
| |
| @Override |
| public String getIdentifier() throws RepositoryException { |
| return this.itemData.getUuid(); |
| } |
| |
| @Override |
| public String getUUID() throws RepositoryException { |
| return getIdentifier(); |
| } |
| |
| @Override |
| public boolean hasNode(final String relPath) throws RepositoryException { |
| String path = makeAbsolutePath(relPath); |
| return getSession().nodeExists(path); |
| } |
| |
| @Override |
| public boolean hasNodes() throws RepositoryException { |
| return getNodes().hasNext(); |
| } |
| |
| @Override |
| public boolean hasProperties() throws RepositoryException { |
| return getProperties().hasNext(); |
| } |
| |
| @Override |
| public boolean hasProperty(final String relPath) throws RepositoryException { |
| String path = makeAbsolutePath(relPath); |
| return getSession().propertyExists(path); |
| } |
| |
| @Override |
| public Property setProperty(final String name, final Value value) throws RepositoryException { |
| ItemData itemData = ItemData.newProperty(getPath() + "/" + name); |
| Property property = new MockProperty(itemData, getSession()); |
| property.setValue(value); |
| addItemOrRemoveIfValueNull(itemData, value); |
| return property; |
| } |
| |
| @Override |
| public Property setProperty(final String name, final Value[] values) throws RepositoryException { |
| ItemData itemData = ItemData.newProperty(getPath() + "/" + name); |
| Property property = new MockProperty(itemData, getSession()); |
| property.setValue(values); |
| addItemOrRemoveIfValueNull(itemData, values); |
| return property; |
| } |
| |
| @Override |
| public Property setProperty(final String name, final String[] values) throws RepositoryException { |
| ItemData itemData = ItemData.newProperty(getPath() + "/" + name); |
| Property property = new MockProperty(itemData, getSession()); |
| property.setValue(values); |
| addItemOrRemoveIfValueNull(itemData, values); |
| return property; |
| } |
| |
| @Override |
| public Property setProperty(final String name, final String value) throws RepositoryException { |
| ItemData itemData = ItemData.newProperty(getPath() + "/" + name); |
| Property property = new MockProperty(itemData, getSession()); |
| property.setValue(value); |
| addItemOrRemoveIfValueNull(itemData, value); |
| return property; |
| } |
| |
| @Override |
| @SuppressWarnings("deprecation") |
| public Property setProperty(final String name, final InputStream value) throws RepositoryException { |
| ItemData itemData = ItemData.newProperty(getPath() + "/" + name); |
| Property property = new MockProperty(itemData, getSession()); |
| property.setValue(value); |
| addItemOrRemoveIfValueNull(itemData, value); |
| return property; |
| } |
| |
| @Override |
| public Property setProperty(final String name, final boolean value) throws RepositoryException { |
| ItemData itemData = ItemData.newProperty(getPath() + "/" + name); |
| Property property = new MockProperty(itemData, getSession()); |
| property.setValue(value); |
| addItem(itemData); |
| return property; |
| } |
| |
| @Override |
| public Property setProperty(final String name, final double value) throws RepositoryException { |
| ItemData itemData = ItemData.newProperty(getPath() + "/" + name); |
| Property property = new MockProperty(itemData, getSession()); |
| property.setValue(value); |
| addItem(itemData); |
| return property; |
| } |
| |
| @Override |
| public Property setProperty(final String name, final long value) throws RepositoryException { |
| ItemData itemData = ItemData.newProperty(getPath() + "/" + name); |
| Property property = new MockProperty(itemData, getSession()); |
| property.setValue(value); |
| addItem(itemData); |
| return property; |
| } |
| |
| @Override |
| public Property setProperty(final String name, final Calendar value) throws RepositoryException { |
| ItemData itemData = ItemData.newProperty(getPath() + "/" + name); |
| Property property = new MockProperty(itemData, getSession()); |
| property.setValue(value); |
| addItemOrRemoveIfValueNull(itemData, value); |
| return property; |
| } |
| |
| @Override |
| public Property setProperty(final String name, final Node value) throws RepositoryException { |
| ItemData itemData = ItemData.newProperty(getPath() + "/" + name); |
| Property property = new MockProperty(itemData, getSession()); |
| property.setValue(value); |
| addItemOrRemoveIfValueNull(itemData, value); |
| return property; |
| } |
| |
| @Override |
| public Property setProperty(final String name, final Binary value) throws RepositoryException { |
| ItemData itemData = ItemData.newProperty(getPath() + "/" + name); |
| Property property = new MockProperty(itemData, getSession()); |
| property.setValue(value); |
| addItemOrRemoveIfValueNull(itemData, value); |
| return property; |
| } |
| |
| @Override |
| public Property setProperty(final String name, final BigDecimal value) throws RepositoryException { |
| ItemData itemData = ItemData.newProperty(getPath() + "/" + name); |
| Property property = new MockProperty(itemData, getSession()); |
| property.setValue(value); |
| addItemOrRemoveIfValueNull(itemData, value); |
| return property; |
| } |
| |
| /** |
| * Adds or overwrites an item and marks the item value as changed. |
| * @param itemData Item data |
| * @throws RepositoryException |
| */ |
| private void addItem(ItemData itemData) throws RepositoryException { |
| getMockedSession().addItem(itemData); |
| this.itemData.setIsChanged(true); |
| } |
| |
| /** |
| * Adds or overwrites an item and marks the item value as changed. |
| * If the given value is null, the item is removed instead. |
| * @param itemData Item data |
| * @throws RepositoryException |
| */ |
| private void addItemOrRemoveIfValueNull(ItemData itemData, Object value) throws RepositoryException { |
| if (value == null) { |
| getMockedSession().removeItem(itemData.getPath()); |
| } |
| else { |
| getMockedSession().addItem(itemData); |
| } |
| this.itemData.setIsChanged(true); |
| } |
| |
| @Override |
| public boolean isNode() { |
| return true; |
| } |
| |
| @Override |
| public boolean isNodeType(final String nodeTypeName) throws RepositoryException { |
| return this.itemData.getNodeType().isNodeType(nodeTypeName); |
| } |
| |
| @Override |
| public NodeType getPrimaryNodeType() throws RepositoryException { |
| return this.itemData.getNodeType(); |
| } |
| |
| @Override |
| public Item getPrimaryItem() throws RepositoryException { |
| // support "jcr:content" node and "jcr:data" property as primary items |
| if (hasProperty(JcrConstants.JCR_DATA)) { |
| return getProperty(JcrConstants.JCR_DATA); |
| } else if (hasNode(JcrConstants.JCR_CONTENT)) { |
| return getNode(JcrConstants.JCR_CONTENT); |
| } else { |
| throw new ItemNotFoundException(); |
| } |
| } |
| |
| @Override |
| public int hashCode() { |
| return itemData.hashCode(); |
| } |
| |
| @Override |
| public boolean equals(Object obj) { |
| if (obj instanceof MockNode) { |
| return itemData.equals(((MockNode)obj).itemData); |
| } |
| return false; |
| } |
| |
| @Override |
| public NodeType[] getMixinNodeTypes() throws RepositoryException { |
| // we have no real mixin support - just assume no mixin nodetypes are set |
| return new NodeType[0]; |
| } |
| |
| @Override |
| public void orderBefore(final String srcChildRelPath, final String destChildRelPath) throws RepositoryException { |
| Item srcChild = srcChildRelPath == null ? null : getMockedSession().getItem(getPath() + "/" + srcChildRelPath); |
| Item destChild = destChildRelPath == null ? null : getMockedSession().getItem(getPath() + "/" + destChildRelPath); |
| getMockedSession().orderBefore(srcChild, destChild); |
| } |
| |
| @Override |
| public NodeDefinition getDefinition() throws RepositoryException { |
| return new MockNodeDefinition(); |
| } |
| |
| // --- unsupported operations --- |
| @Override |
| public Property setProperty(final String name, final Value value, final int type) throws RepositoryException { |
| throw new UnsupportedOperationException(); |
| } |
| |
| @Override |
| public Property setProperty(final String name, final Value[] values, final int type) throws RepositoryException { |
| throw new UnsupportedOperationException(); |
| } |
| |
| @Override |
| public Property setProperty(final String name, final String[] values, final int type) throws RepositoryException { |
| throw new UnsupportedOperationException(); |
| } |
| |
| @Override |
| public Property setProperty(final String name, final String value, final int type) throws RepositoryException { |
| throw new UnsupportedOperationException(); |
| } |
| |
| @Override |
| public void addMixin(final String mixinName) throws RepositoryException { |
| throw new UnsupportedOperationException(); |
| } |
| |
| @Override |
| public boolean canAddMixin(final String mixinName) throws RepositoryException { |
| throw new UnsupportedOperationException(); |
| } |
| |
| @Override |
| public void cancelMerge(final Version version) throws RepositoryException { |
| throw new UnsupportedOperationException(); |
| } |
| |
| @Override |
| public Version checkin() throws RepositoryException { |
| throw new UnsupportedOperationException(); |
| } |
| |
| @Override |
| public void checkout() throws RepositoryException { |
| throw new UnsupportedOperationException(); |
| } |
| |
| @Override |
| public void doneMerge(final Version version) throws RepositoryException { |
| throw new UnsupportedOperationException(); |
| } |
| |
| @Override |
| public Version getBaseVersion() throws RepositoryException { |
| throw new UnsupportedOperationException(); |
| } |
| |
| @Override |
| public String getCorrespondingNodePath(final String workspaceName) throws RepositoryException { |
| throw new UnsupportedOperationException(); |
| } |
| |
| @Override |
| public int getIndex() throws RepositoryException { |
| throw new UnsupportedOperationException(); |
| } |
| |
| @Override |
| public Lock getLock() throws RepositoryException { |
| throw new UnsupportedOperationException(); |
| } |
| |
| @Override |
| public PropertyIterator getReferences() throws RepositoryException { |
| throw new UnsupportedOperationException(); |
| } |
| |
| @Override |
| public VersionHistory getVersionHistory() throws RepositoryException { |
| throw new UnsupportedOperationException(); |
| } |
| |
| @Override |
| public boolean holdsLock() throws RepositoryException { |
| throw new UnsupportedOperationException(); |
| } |
| |
| @Override |
| public boolean isCheckedOut() throws RepositoryException { |
| throw new UnsupportedOperationException(); |
| } |
| |
| @Override |
| public boolean isLocked() throws RepositoryException { |
| throw new UnsupportedOperationException(); |
| } |
| |
| @Override |
| public Lock lock(final boolean isDeep, final boolean isSessionScoped) throws RepositoryException { |
| throw new UnsupportedOperationException(); |
| } |
| |
| @Override |
| public NodeIterator merge(final String srcWorkspace, final boolean bestEffort) throws RepositoryException { |
| throw new UnsupportedOperationException(); |
| } |
| |
| @Override |
| public void removeMixin(final String mixinName) throws RepositoryException { |
| throw new UnsupportedOperationException(); |
| } |
| |
| @Override |
| public void restore(final String versionName, final boolean removeExisting) throws RepositoryException { |
| throw new UnsupportedOperationException(); |
| } |
| |
| @Override |
| public void restore(final Version version, final boolean removeExisting) throws RepositoryException { |
| throw new UnsupportedOperationException(); |
| } |
| |
| @Override |
| public void restore(final Version version, final String relPath, final boolean removeExisting) throws RepositoryException { |
| throw new UnsupportedOperationException(); |
| } |
| |
| @Override |
| public void restoreByLabel(final String versionLabel, final boolean removeExisting) throws RepositoryException { |
| throw new UnsupportedOperationException(); |
| } |
| |
| @Override |
| public void unlock() throws RepositoryException { |
| throw new UnsupportedOperationException(); |
| } |
| |
| @Override |
| public void update(final String srcWorkspaceName) throws RepositoryException { |
| throw new UnsupportedOperationException(); |
| } |
| |
| @Override |
| public void followLifecycleTransition(final String transition) throws RepositoryException { |
| throw new UnsupportedOperationException(); |
| } |
| |
| @Override |
| public String[] getAllowedLifecycleTransistions() throws RepositoryException { |
| throw new UnsupportedOperationException(); |
| } |
| |
| @Override |
| public PropertyIterator getReferences(final String name) throws RepositoryException { |
| throw new UnsupportedOperationException(); |
| } |
| |
| @Override |
| public NodeIterator getSharedSet() throws RepositoryException { |
| throw new UnsupportedOperationException(); |
| } |
| |
| @Override |
| public PropertyIterator getWeakReferences() throws RepositoryException { |
| throw new UnsupportedOperationException(); |
| } |
| |
| @Override |
| public PropertyIterator getWeakReferences(final String name) throws RepositoryException { |
| throw new UnsupportedOperationException(); |
| } |
| |
| @Override |
| public void removeShare() throws RepositoryException { |
| throw new UnsupportedOperationException(); |
| } |
| |
| @Override |
| public void removeSharedSet() throws RepositoryException { |
| throw new UnsupportedOperationException(); |
| } |
| |
| @Override |
| public void setPrimaryType(final String nodeTypeName) throws RepositoryException { |
| throw new UnsupportedOperationException(); |
| } |
| |
| } |