<commit_before>/*
 * 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.memory;

import org.apache.commons.collections.IteratorUtils;
import org.apache.commons.collections.Predicate;
import org.apache.commons.collections.PredicateUtils;
import org.apache.jackrabbit.oak.api.PropertyState;
import org.apache.jackrabbit.oak.spi.state.ChildNodeEntry;
import org.apache.jackrabbit.oak.spi.state.NodeState;
import org.apache.jackrabbit.oak.spi.state.NodeStateDiff;
import org.apache.jackrabbit.oak.spi.state.ProxyNodeState;

import java.util.Iterator;
import java.util.Map;

public class ModifiedNodeState extends ProxyNodeState {

    private final Map<String, PropertyState> properties;

    private final Map<String, NodeState> nodes;

    public ModifiedNodeState(
            NodeState base,
            Map<String, PropertyState> properties,
            Map<String, NodeState> nodes) {
        super(base);
        this.properties = properties;
        this.nodes = nodes;
    }

    NodeState getBase() {
        return delegate;
    }

    void diffAgainstBase(NodeStateDiff diff) {
        for (Map.Entry<String, PropertyState> entry : properties.entrySet()) {
            PropertyState before = super.getProperty(entry.getKey());
            PropertyState after = entry.getValue();
            if (after == null) {
                assert before != null;
                diff.propertyDeleted(before);
            } else if (before == null) {
                diff.propertyAdded(after);
            } else {
                diff.propertyChanged(before, after);
            }
        }

        for (Map.Entry<String, NodeState> entry : nodes.entrySet()) {
            String name = entry.getKey();
            NodeState before = super.getChildNode(name);
            NodeState after = entry.getValue();
            if (after == null) {
                assert before != null;
                diff.childNodeDeleted(name, before);
            } else if (before == null) {
                diff.childNodeAdded(name, after);
            } else {
                diff.childNodeChanged(name, before, after);
            }
        }
    }

    //---------------------------------------------------------< NodeState >--

    @Override
    public PropertyState getProperty(String name) {
        if (properties.containsKey(name)) {
            return properties.get(name);
        } else {
            return super.getProperty(name);
        }
    }

    @Override
    public long getPropertyCount() {
        long count = super.getPropertyCount();
        for (Map.Entry<String, PropertyState> entry : properties.entrySet()) {
            if (super.getProperty(entry.getKey()) != null) {
                if (entry.getValue() == null) {
                    count--;
                }
            } else {
                if (entry.getValue() != null) {
                    count++;
                }
            }
        }
        return count;
    }

    @Override
    public Iterable<? extends PropertyState> getProperties() {
        if (properties.isEmpty()) {
            return super.getProperties(); // shortcut
        }
        final Iterable<? extends PropertyState> unmodified =
                super.getProperties();
        final Iterable<? extends PropertyState> modified =
                properties.values();
        return new Iterable<PropertyState>() {
            @Override @SuppressWarnings("unchecked")
            public Iterator<PropertyState> iterator() {
                Iterator<PropertyState> a = IteratorUtils.filteredIterator(
                        unmodified.iterator(),
                        new UnmodifiedPropertyPredicate());
                Iterator<PropertyState> b = IteratorUtils.filteredIterator(
                        modified.iterator(),
                        PredicateUtils.notNullPredicate());
                return IteratorUtils.chainedIterator(a, b);
            }
        };
    }

    @Override
    public NodeState getChildNode(String name) {
        if (nodes.containsKey(name)) {
            return nodes.get(name);
        } else {
            return super.getChildNode(name);
        }
    }

    @Override
    public long getChildNodeCount() {
        long count = super.getChildNodeCount();
        for (Map.Entry<String, NodeState> entry : nodes.entrySet()) {
            if (super.getChildNode(entry.getKey()) != null) {
                if (entry.getValue() == null) {
                    count--;
                }
            } else {
                if (entry.getValue() != null) {
                    count++;
                }
            }
        }
        return count;
    }

    @Override
    public Iterable<? extends ChildNodeEntry> getChildNodeEntries() {
        if (nodes.isEmpty()) {
            return super.getChildNodeEntries(); // shortcut
        }
        final Iterable<? extends ChildNodeEntry> unmodified =
                super.getChildNodeEntries();
        final Iterable<? extends ChildNodeEntry> modified =
                MemoryChildNodeEntry.iterable(nodes);
        return new Iterable<ChildNodeEntry>() {
            @Override @SuppressWarnings("unchecked")
            public Iterator<ChildNodeEntry> iterator() {
                Iterator<ChildNodeEntry> a = IteratorUtils.filteredIterator(
                        unmodified.iterator(),
                        new UnmodifiedChildNodePredicate());
                Iterator<ChildNodeEntry> b = IteratorUtils.filteredIterator(
                        modified.iterator(),
                        new UndeletedChildNodePredicate());
                return IteratorUtils.chainedIterator(a, b);
            }
        };
    }

    private class UnmodifiedPropertyPredicate implements Predicate {

        @Override
        public boolean evaluate(Object object) {
            if (object instanceof PropertyState) {
                PropertyState property = ((PropertyState) object);<commit_msg>OAK-68: Extension point for commit validation<commit_after>/*
 * 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.memory;

import org.apache.commons.collections.IteratorUtils;
import org.apache.commons.collections.Predicate;
import org.apache.commons.collections.PredicateUtils;
import org.apache.jackrabbit.oak.api.PropertyState;
import org.apache.jackrabbit.oak.spi.state.AbstractNodeState;
import org.apache.jackrabbit.oak.spi.state.ChildNodeEntry;
import org.apache.jackrabbit.oak.spi.state.NodeState;
import org.apache.jackrabbit.oak.spi.state.NodeStateDiff;

import java.util.Iterator;
import java.util.Map;

public class ModifiedNodeState extends AbstractNodeState {

    private final NodeState base;

    private final Map<String, PropertyState> properties;

    private final Map<String, NodeState> nodes;

    public ModifiedNodeState(
            NodeState base,
            Map<String, PropertyState> properties,
            Map<String, NodeState> nodes) {
        this.base = base;
        this.properties = properties;
        this.nodes = nodes;
    }

    NodeState getBase() {
        return base;
    }

    void diffAgainstBase(NodeStateDiff diff) {
        for (Map.Entry<String, PropertyState> entry : properties.entrySet()) {
            PropertyState before = base.getProperty(entry.getKey());
            PropertyState after = entry.getValue();
            if (after == null) {
                assert before != null;
                diff.propertyDeleted(before);
            } else if (before == null) {
                diff.propertyAdded(after);
            } else {
                diff.propertyChanged(before, after);
            }
        }

        for (Map.Entry<String, NodeState> entry : nodes.entrySet()) {
            String name = entry.getKey();
            NodeState before = base.getChildNode(name);
            NodeState after = entry.getValue();
            if (after == null) {
                assert before != null;
                diff.childNodeDeleted(name, before);
            } else if (before == null) {
                diff.childNodeAdded(name, after);
            } else {
                diff.childNodeChanged(name, before, after);
            }
        }
    }

    //---------------------------------------------------------< NodeState >--

    @Override
    public PropertyState getProperty(String name) {
        if (properties.containsKey(name)) {
            return properties.get(name);
        } else {
            return base.getProperty(name);
        }
    }

    @Override
    public long getPropertyCount() {
        long count = base.getPropertyCount();
        for (Map.Entry<String, PropertyState> entry : properties.entrySet()) {
            if (base.getProperty(entry.getKey()) != null) {
                if (entry.getValue() == null) {
                    count--;
                }
            } else {
                if (entry.getValue() != null) {
                    count++;
                }
            }
        }
        return count;
    }

    @Override
    public Iterable<? extends PropertyState> getProperties() {
        if (properties.isEmpty()) {
            return base.getProperties(); // shortcut
        }
        final Iterable<? extends PropertyState> unmodified =
                base.getProperties();
        final Iterable<? extends PropertyState> modified =
                properties.values();
        return new Iterable<PropertyState>() {
            @Override @SuppressWarnings("unchecked")
            public Iterator<PropertyState> iterator() {
                Iterator<PropertyState> a = IteratorUtils.filteredIterator(
                        unmodified.iterator(),
                        new UnmodifiedPropertyPredicate());
                Iterator<PropertyState> b = IteratorUtils.filteredIterator(
                        modified.iterator(),
                        PredicateUtils.notNullPredicate());
                return IteratorUtils.chainedIterator(a, b);
            }
        };
    }

    @Override
    public NodeState getChildNode(String name) {
        if (nodes.containsKey(name)) {
            return nodes.get(name);
        } else {
            return base.getChildNode(name);
        }
    }

    @Override
    public long getChildNodeCount() {
        long count = base.getChildNodeCount();
        for (Map.Entry<String, NodeState> entry : nodes.entrySet()) {
            if (base.getChildNode(entry.getKey()) != null) {
                if (entry.getValue() == null) {
                    count--;
                }
            } else {
                if (entry.getValue() != null) {
                    count++;
                }
            }
        }
        return count;
    }

    @Override
    public Iterable<? extends ChildNodeEntry> getChildNodeEntries() {
        if (nodes.isEmpty()) {
            return base.getChildNodeEntries(); // shortcut
        }
        final Iterable<? extends ChildNodeEntry> unmodified =
                base.getChildNodeEntries();
        final Iterable<? extends ChildNodeEntry> modified =
                MemoryChildNodeEntry.iterable(nodes);
        return new Iterable<ChildNodeEntry>() {
            @Override @SuppressWarnings("unchecked")
            public Iterator<ChildNodeEntry> iterator() {
                Iterator<ChildNodeEntry> a = IteratorUtils.filteredIterator(
                        unmodified.iterator(),
                        new UnmodifiedChildNodePredicate());
                Iterator<ChildNodeEntry> b = IteratorUtils.filteredIterator(
                        modified.iterator(),
                        new UndeletedChildNodePredicate());
                return IteratorUtils.chainedIterator(a, b);
            }
        };
    }

    private class UnmodifiedPropertyPredicate implements Predicate {

        @Override
        public boolean evaluate(Object object) {
            if (object instanceof PropertyState) {
                PropertyState property = ((PropertyState) object);
{'fraction_non_alphanumeric': 0.10127426285375611, 'fraction_numerical': 0.0007408504963698325, 'mean_word_length': 1.9212291711750704, 'pattern_counts': {'":': 0, '<': 49, '<?xml version=': 0, '>': 49, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4744547', 'n_tokens_mistral': 3313, 'n_tokens_neox': 3190, 'n_words': 841}