Package org.apache.jackrabbit.oak.plugins.segment

Source Code of org.apache.jackrabbit.oak.plugins.segment.SegmentNodeState

/*
* 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.oak.plugins.segment;

import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.collect.Lists.newArrayListWithCapacity;
import static org.apache.jackrabbit.JcrConstants.JCR_MIXINTYPES;
import static org.apache.jackrabbit.JcrConstants.JCR_PRIMARYTYPE;
import static org.apache.jackrabbit.oak.plugins.memory.EmptyNodeState.EMPTY_NODE;
import static org.apache.jackrabbit.oak.plugins.memory.EmptyNodeState.MISSING_NODE;

import java.util.Collections;
import java.util.List;

import javax.annotation.CheckForNull;
import javax.annotation.Nonnull;

import org.apache.jackrabbit.oak.api.PropertyState;
import org.apache.jackrabbit.oak.plugins.memory.MemoryChildNodeEntry;
import org.apache.jackrabbit.oak.spi.state.AbstractNodeState;
import org.apache.jackrabbit.oak.spi.state.ChildNodeEntry;
import org.apache.jackrabbit.oak.spi.state.NodeBuilder;
import org.apache.jackrabbit.oak.spi.state.NodeState;
import org.apache.jackrabbit.oak.spi.state.NodeStateDiff;

import com.google.common.base.Objects;

public class SegmentNodeState extends Record implements NodeState {

    static boolean fastEquals(NodeState a, NodeState b) {
        return a instanceof SegmentNodeState
                && b instanceof SegmentNodeState
                && Objects.equal(
                        ((SegmentNodeState) a).getRecordId(),
                        ((SegmentNodeState) b).getRecordId());
    }

    private RecordId templateId = null;

    private Template template = null;

    public SegmentNodeState(Segment segment, RecordId id) {
        super(segment, id);
    }

    RecordId getTemplateId() {
        getTemplate(); // force loading of the template
        return templateId;
    }

    synchronized Template getTemplate() {
        if (template == null) {
            Segment segment = getSegment();
            templateId = segment.readRecordId(getOffset(0));
            template = segment.readTemplate(templateId);
        }
        return template;
    }

    MapRecord getChildNodeMap() {
        Segment segment = getSegment();
        return segment.readMap(segment.readRecordId(getOffset(0, 1)));
    }

    @Override
    public boolean exists() {
        return true;
    }

    @Override
    public long getPropertyCount() {
        Template template = getTemplate();
        long count = template.getPropertyTemplates().length;
        if (template.getPrimaryType() != null) {
            count++;
        }
        if (template.getMixinTypes() != null) {
            count++;
        }
        return count;
    }

    @Override
    public boolean hasProperty(String name) {
        checkNotNull(name);
        Template template = getTemplate();
        if (JCR_PRIMARYTYPE.equals(name)) {
            return template.getPrimaryType() != null;
        } else if (JCR_MIXINTYPES.equals(name)) {
            return template.getMixinTypes() != null;
        } else {
            return template.getPropertyTemplate(name) != null;
        }
    }

    @Override @CheckForNull
    public PropertyState getProperty(String name) {
        checkNotNull(name);
        Template template = getTemplate();
        if (JCR_PRIMARYTYPE.equals(name)) {
            return template.getPrimaryType();
        } else if (JCR_MIXINTYPES.equals(name)) {
            return template.getMixinTypes();
        } else {
            PropertyTemplate propertyTemplate =
                    template.getPropertyTemplate(name);
            if (propertyTemplate != null) {
                Segment segment = getSegment();
                int ids = 1 + propertyTemplate.getIndex();
                if (template.getChildName() != Template.ZERO_CHILD_NODES) {
                    ids++;
                }
                return new SegmentPropertyState(
                        segment, segment.readRecordId(getOffset(0, ids)),
                        propertyTemplate);
            } else {
                return null;
            }
        }
    }

    @Override @Nonnull
    public Iterable<PropertyState> getProperties() {
        Template template = getTemplate();
        PropertyTemplate[] propertyTemplates = template.getPropertyTemplates();
        List<PropertyState> list =
                newArrayListWithCapacity(propertyTemplates.length + 2);

        PropertyState primaryType = template.getPrimaryType();
        if (primaryType != null) {
            list.add(primaryType);
        }

        PropertyState mixinTypes = template.getMixinTypes();
        if (mixinTypes != null) {
            list.add(mixinTypes);
        }

        Segment segment = getSegment();
        int ids = 1;
        if (template.getChildName() != Template.ZERO_CHILD_NODES) {
            ids++;
        }
        for (int i = 0; i < propertyTemplates.length; i++) {
            RecordId propertyId = segment.readRecordId(getOffset(0, ids++));
            list.add(new SegmentPropertyState(
                    segment, propertyId, propertyTemplates[i]));
        }

        return list;
    }

    @Override
    public boolean getBoolean(String name) {
        return AbstractNodeState.getBoolean(this, name);
    }

    @Override
    public long getLong(String name) {
        return AbstractNodeState.getLong(this, name);
    }

    @Override
    public String getString(String name) {
        return AbstractNodeState.getString(this, name);
    }

    @Override
    public String getName(String name) {
        return AbstractNodeState.getName(this, name);
    }

    @Override
    public Iterable<String> getNames(String name) {
        return AbstractNodeState.getNames(this, name);
    }

    @Override
    public long getChildNodeCount(long max) {
        String childName = getTemplate().getChildName();
        if (childName == Template.ZERO_CHILD_NODES) {
            return 0;
        } else if (childName == Template.MANY_CHILD_NODES) {
            return getChildNodeMap().size();
        } else {
            return 1;
        }
    }

    @Override
    public boolean hasChildNode(String name) {
        checkArgument(!checkNotNull(name).isEmpty());
        String childName = getTemplate().getChildName();
        if (childName == Template.ZERO_CHILD_NODES) {
            return false;
        } else if (childName == Template.MANY_CHILD_NODES) {
            return getChildNodeMap().getEntry(name) != null;
        } else {
            return childName.equals(name);
        }
    }

    @Override @Nonnull
    public NodeState getChildNode(String name) {
        // checkArgument(!checkNotNull(name).isEmpty()); // TODO
        String childName = getTemplate().getChildName();
        if (childName == Template.ZERO_CHILD_NODES) {
            return MISSING_NODE;
        } else if (childName == Template.MANY_CHILD_NODES) {
            MapEntry child = getChildNodeMap().getEntry(name);
            if (child != null) {
                return child.getNodeState();
            } else {
                return MISSING_NODE;
            }
        } else {
            if (childName.equals(name)) {
                Segment segment = getSegment();
                RecordId childNodeId = segment.readRecordId(getOffset(0, 1));
                return new SegmentNodeState(segment, childNodeId);
            } else {
                return MISSING_NODE;
            }
        }
    }

    @Override @Nonnull
    public Iterable<String> getChildNodeNames() {
        String childName = getTemplate().getChildName();
        if (childName == Template.ZERO_CHILD_NODES) {
            return Collections.emptyList();
        } else if (childName == Template.MANY_CHILD_NODES) {
            return getChildNodeMap().getKeys();
        } else {
            return Collections.singletonList(childName);
        }
    }

    @Override @Nonnull
    public Iterable<? extends ChildNodeEntry> getChildNodeEntries() {
        String childName = getTemplate().getChildName();
        if (childName == Template.ZERO_CHILD_NODES) {
            return Collections.emptyList();
        } else if (childName == Template.MANY_CHILD_NODES) {
            return getChildNodeMap().getEntries();
        } else {
            Segment segment = getSegment();
            RecordId childNodeId = segment.readRecordId(getOffset(0, 1));
            return Collections.singletonList(new MemoryChildNodeEntry(
                    childName, new SegmentNodeState(segment, childNodeId)));
        }
    }

    @Override @Nonnull
    public NodeBuilder builder() {
        // TODO: avoid the Segment.store reference
        return new SegmentRootBuilder(this, getSegment().store.getWriter());
    }

    @Override
    public boolean compareAgainstBaseState(NodeState base, NodeStateDiff diff) {
        if (base == this) {
             return true; // no changes
        } else if (base == EMPTY_NODE || !base.exists()) { // special case
            return getTemplate().compareAgainstEmptyState(
                    getSegment(), getRecordId(), diff);
        } else if (base instanceof SegmentNodeState) {
            SegmentNodeState that = (SegmentNodeState) base;
            return getRecordId().equals(that.getRecordId())
                || getTemplate().compareAgainstBaseState(
                        getSegment(), getRecordId(),
                        that.getTemplate(), that.getRecordId(),
                        diff);
        } else {
            // fallback
            return AbstractNodeState.compareAgainstBaseState(this, base, diff);
        }
    }

    @Override
    public boolean equals(Object object) {
        if (this == object) {
            return true;
        } else if (object instanceof SegmentNodeState) {
            SegmentNodeState that = (SegmentNodeState) object;
            if (getRecordId().equals(that.getRecordId())) {
                return true;
            } else {
                Template template = getTemplate();
                return template.equals(that.getTemplate())
                        && template.compare(
                                getSegment(), getRecordId(),
                                that.getSegment(), that.getRecordId());
            }
        } else {
            return super.equals(object); // TODO
        }
    }

}
TOP

Related Classes of org.apache.jackrabbit.oak.plugins.segment.SegmentNodeState

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.