This is an automated email from the ASF dual-hosted git repository.

reschke pushed a commit to branch trunk
in repository https://gitbox.apache.org/repos/asf/jackrabbit-oak.git


The following commit(s) were added to refs/heads/trunk by this push:
     new d86fc37969 Revert "OAK-11617: Provide oak-run commands to analyze and 
fix inconsistencie… (#2328)"
d86fc37969 is described below

commit d86fc3796996d5a22d8279e4f0d64e214b4083c5
Author: Julian Reschke <[email protected]>
AuthorDate: Sat Jun 28 06:20:23 2025 +0100

    Revert "OAK-11617: Provide oak-run commands to analyze and fix 
inconsistencie… (#2328)"
    
    This reverts commit a16b36f159783701b2b06f5871c26c4bd4eb810b.
---
 .../oak/plugins/name/NamespaceRegistryModel.java   | 456 ---------------------
 .../plugins/name/ReadOnlyNamespaceRegistry.java    |  65 ++-
 .../oak/plugins/name/NamespaceRegistryTest.java    | 263 ------------
 .../apache/jackrabbit/oak/run/AvailableModes.java  |   1 -
 .../oak/run/NamespaceRegistryCommand.java          | 169 --------
 .../oak/run/NamespaceRegistryOptions.java          | 104 -----
 .../oak/run/NamespaceRegistryCommandTest.java      | 107 -----
 7 files changed, 54 insertions(+), 1111 deletions(-)

diff --git 
a/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/name/NamespaceRegistryModel.java
 
b/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/name/NamespaceRegistryModel.java
deleted file mode 100755
index 99868effdb..0000000000
--- 
a/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/name/NamespaceRegistryModel.java
+++ /dev/null
@@ -1,456 +0,0 @@
-/*
- * 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.name;
-
-import java.io.BufferedWriter;
-import java.io.IOException;
-import java.io.OutputStream;
-import java.io.OutputStreamWriter;
-import java.io.Writer;
-import java.nio.charset.StandardCharsets;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Objects;
-import java.util.Set;
-import java.util.stream.Collectors;
-
-import javax.jcr.RepositoryException;
-
-import org.apache.jackrabbit.JcrConstants;
-import org.apache.jackrabbit.oak.api.Root;
-import org.apache.jackrabbit.util.Text;
-import org.apache.jackrabbit.oak.api.CommitFailedException;
-import org.apache.jackrabbit.oak.api.PropertyState;
-import org.apache.jackrabbit.oak.api.Tree;
-import org.apache.jackrabbit.oak.commons.collections.IterableUtils;
-import org.apache.jackrabbit.oak.commons.collections.SetUtils;
-import org.apache.jackrabbit.oak.commons.collections.StreamUtils;
-import org.apache.jackrabbit.oak.spi.namespace.NamespaceConstants;
-import org.apache.jackrabbit.oak.spi.nodetype.NodeTypeConstants;
-
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
-
-import static org.apache.jackrabbit.JcrConstants.JCR_PRIMARYTYPE;
-import static org.apache.jackrabbit.oak.api.Type.STRING;
-import static org.apache.jackrabbit.oak.api.Type.STRINGS;
-import static 
org.apache.jackrabbit.oak.spi.namespace.NamespaceConstants.REP_NAMESPACES;
-
-/**
- * A model of the namespace registry, containing the mappings from prefixes to
- * namespace URIs and vice versa.
- * <p>
- * The model is created from the namespace registry stored in the repository.
- * It can be used to check the consistency of the registry, repair it if
- * possible, and apply the changes back to the repository.
- */
-public final class NamespaceRegistryModel {
-
-    private final Map<String, String> prefixToNamespaceMap;
-    private final Map<String, String> encodedNamespaceToPrefixMap;
-
-    private final Set<String> registeredPrefixes;
-    private final Set<String> registeredNamespacesEncoded;
-    private final Set<String> mappedPrefixes;
-    private final Set<String> mappedNamespacesEncoded;
-    private final Set<String> mappedToPrefixes;
-    private final Set<String> mappedToNamespacesEncoded;
-    private final Set<String> allPrefixes;
-    private final Set<String> allNamespacesEncoded;
-    private final Set<String> consistentPrefixes;
-    private final Set<String> consistentNamespacesEncoded;
-    private final int registrySize;
-
-    private final Set<String> duplicatePrefixes;
-    private final Set<String> duplicateNamespacesEncoded;
-
-    private final Set<String> danglingPrefixes;
-    private final Set<String> danglingNamespacesEncoded;
-
-    private volatile boolean consistent = false;
-    private volatile boolean fixable = false;
-
-    private NamespaceRegistryModel(
-            List<String> registeredPrefixesList, List<String> 
registeredNamespacesEncodedList,
-            // prefixes to URIs
-            Map<String, String> prefixToNamespaceMap,
-            // encoded URIs to prefixes
-            Map<String, String> encodedNamespaceToPrefixMap) {
-        // ignore the empty namespace which is not mapped
-        registeredPrefixes = registeredPrefixesList.stream().filter(s -> 
!(Objects.isNull(s) || s.isEmpty())).collect(Collectors.toSet());
-        duplicatePrefixes = findDuplicates(registeredPrefixesList);
-        registeredNamespacesEncoded = 
registeredNamespacesEncodedList.stream().filter(s -> !(Objects.isNull(s) || 
s.isEmpty())).collect(Collectors.toSet());
-        duplicateNamespacesEncoded = 
findDuplicates(registeredNamespacesEncodedList);
-        this.prefixToNamespaceMap = new HashMap<>(prefixToNamespaceMap);
-        this.encodedNamespaceToPrefixMap = new 
HashMap<>(encodedNamespaceToPrefixMap);
-        mappedPrefixes = this.prefixToNamespaceMap.keySet();
-        mappedNamespacesEncoded = this.encodedNamespaceToPrefixMap.keySet();
-        mappedToPrefixes = new HashSet<>(encodedNamespaceToPrefixMap.values());
-        mappedToNamespacesEncoded = 
this.prefixToNamespaceMap.values().stream().map(Namespaces::encodeUri).collect(Collectors.toSet());
-        allPrefixes = SetUtils.union(SetUtils.union(registeredPrefixes, 
mappedPrefixes), mappedToPrefixes);
-        allNamespacesEncoded = 
SetUtils.union(SetUtils.union(registeredNamespacesEncoded, 
mappedNamespacesEncoded), mappedToNamespacesEncoded);
-        registrySize = Math.max(allPrefixes.size(), 
allNamespacesEncoded.size());
-        consistentPrefixes = 
SetUtils.intersection(SetUtils.intersection(registeredPrefixes, 
mappedPrefixes), mappedToPrefixes);
-        consistentNamespacesEncoded = 
SetUtils.intersection(SetUtils.intersection(registeredNamespacesEncoded, 
mappedNamespacesEncoded), mappedToNamespacesEncoded);
-        danglingPrefixes = SetUtils.difference(registeredPrefixes, 
SetUtils.union(mappedPrefixes, mappedToPrefixes));
-        danglingNamespacesEncoded = 
SetUtils.difference(registeredNamespacesEncoded, 
SetUtils.union(mappedNamespacesEncoded, mappedToNamespacesEncoded));
-
-        boolean sizeMatches = duplicatePrefixes.isEmpty()
-                && duplicateNamespacesEncoded.isEmpty()
-                && consistentNamespacesEncoded.size() == 
allNamespacesEncoded.size()
-                && consistentPrefixes.size() == allPrefixes.size();
-        boolean doesRoundtrip = true;
-        if (sizeMatches) {
-            for (String prefix : mappedPrefixes) {
-                String revMapped = 
encodedNamespaceToPrefixMap.get(Namespaces.encodeUri(prefixToNamespaceMap.get(prefix)));
-                if (revMapped == null || !revMapped.equals(prefix)) {
-                    doesRoundtrip = false;
-                    break;
-                }
-            }
-            if (doesRoundtrip) {
-                for (String ns : mappedNamespacesEncoded) {
-                    String uri = 
prefixToNamespaceMap.get(encodedNamespaceToPrefixMap.get(ns));
-                    if (uri == null || !Namespaces.encodeUri(uri).equals(ns)) {
-                        doesRoundtrip = false;
-                        break;
-                    }
-                }
-            }
-        }
-        consistent = sizeMatches && doesRoundtrip;
-        fixable = consistent;
-        if (!consistent && doesRoundtrip) {
-            fixable = registrySize == SetUtils.union(mappedPrefixes, 
mappedToPrefixes).size()
-                    && registrySize == SetUtils.union(mappedNamespacesEncoded, 
mappedToNamespacesEncoded).size();
-        }
-    }
-
-    /**
-     * Creates a new {@link NamespaceRegistryModel} from the namespace registry
-     * stored in the system tree under the given repository {@link Root}.
-     *
-     * @param root the root of the repository
-     * @return a new {@link NamespaceRegistryModel} or {@code null} if the
-     *         namespace registry does not exist
-     */
-    public static @Nullable NamespaceRegistryModel create(@NotNull Root root) {
-        Tree rootTree = root.getTree("/");
-        Tree namespaces = rootTree.getChild( JcrConstants.JCR_SYSTEM 
).getChild(REP_NAMESPACES);
-        if (namespaces.exists()) {
-            Tree nsdata = namespaces.getChild(NamespaceConstants.REP_NSDATA);
-            Map<String, String> prefixToNamespaceMap = new HashMap<>();
-            Map<String, String> namespaceToPrefixMap = new HashMap<>();
-            for (PropertyState propertyState : namespaces.getProperties()) {
-                String prefix = propertyState.getName();
-                if (!prefix.equals(NodeTypeConstants.JCR_PRIMARYTYPE)) {
-                    prefixToNamespaceMap.put(prefix, 
propertyState.getValue(STRING));
-                }
-            }
-            for (PropertyState propertyState : nsdata.getProperties()) {
-                String encodedUri = propertyState.getName();
-                switch (encodedUri) {
-                    case NamespaceConstants.REP_PREFIXES:
-                    case NamespaceConstants.REP_URIS:
-                    case NodeTypeConstants.JCR_PRIMARYTYPE:
-                        break;
-                    default:
-                        namespaceToPrefixMap.put(encodedUri, 
propertyState.getValue(STRING));
-                }
-            }
-            Iterable<String> uris = 
Objects.requireNonNull(nsdata.getProperty(NamespaceConstants.REP_URIS))
-                    .getValue(STRINGS);
-            return new NamespaceRegistryModel(
-                    
Arrays.asList(IterableUtils.toArray(Objects.requireNonNull(nsdata.getProperty(NamespaceConstants.REP_PREFIXES)).getValue(STRINGS),
 String.class)),
-                    
StreamUtils.toStream(uris).map(Namespaces::encodeUri).collect(Collectors.toList()),
-                    prefixToNamespaceMap, namespaceToPrefixMap);
-        } else {
-            return null;
-        }
-    }
-
-    /**
-     * Creates a new {@link NamespaceRegistryModel} with the given mappings. 
Used by {@see NamespaceRegistryCommand} to
-     * repair a namespace registry that cannot be fixed automatically because 
mapping information is missing.
-     *
-     * @param additionalPrefixToUrisMappings a map from prefixes to namespace 
URIs
-     * @return a new {@link NamespaceRegistryModel}
-     */
-    public NamespaceRegistryModel setMappings(@NotNull Map<String, String> 
additionalPrefixToUrisMappings) {
-        List<String> newRegisteredPrefixesList = new 
ArrayList<>(registeredPrefixes);
-        HashMap<String, String> newPrefixToNamespaceMap = new 
HashMap<>(prefixToNamespaceMap);
-        List<String> newRegisteredNamespacesEncodedList = new 
ArrayList<>(registeredNamespacesEncoded);
-        HashMap<String, String> newEncodedNamespaceToPrefixMap = new 
HashMap<>(encodedNamespaceToPrefixMap);
-        for (Map.Entry<String, String> entry : 
additionalPrefixToUrisMappings.entrySet()) {
-            String prefix = entry.getKey();
-            String uri = entry.getValue();
-            String encodedUri = Namespaces.encodeUri(uri);
-
-            if (!newRegisteredPrefixesList.contains(prefix)) {
-                newRegisteredPrefixesList.add(prefix);
-            }
-            if (!newRegisteredNamespacesEncodedList.contains(encodedUri)) {
-                newRegisteredNamespacesEncodedList.add(encodedUri);
-            }
-            String previousUri = newPrefixToNamespaceMap.get(prefix);
-            newPrefixToNamespaceMap.put(prefix, uri);
-            if (previousUri != null) {
-                String previousEncodedUri = Namespaces.encodeUri(previousUri);
-                newRegisteredNamespacesEncodedList.remove(previousEncodedUri);
-                newEncodedNamespaceToPrefixMap.remove(previousEncodedUri);
-            }
-            newEncodedNamespaceToPrefixMap.put(encodedUri, prefix);
-        }
-        return new NamespaceRegistryModel(newRegisteredPrefixesList, 
newRegisteredNamespacesEncodedList,
-                newPrefixToNamespaceMap, newEncodedNamespaceToPrefixMap);
-    }
-
-    /** Tries to repair the namespace registry model by fixing the mappings
-     * from prefixes to namespace URIs and vice versa. If the model is not
-     * fixable, it returns the original model.
-     *
-     * @return a new {@link NamespaceRegistryModel} with fixed mappings or the
-     *         original model if it cannot be fixed
-     */
-    public NamespaceRegistryModel tryRegistryRepair() {
-        if (fixable) {
-            List<String> fixedRegisteredPrefixesList = new ArrayList<>();
-            HashMap<String, String> fixedPrefixToNamespaceMap = new 
HashMap<>();
-            for (String prefix : allPrefixes) {
-                if (mappedPrefixes.contains(prefix)) {
-                    fixedRegisteredPrefixesList.add(prefix);
-                    fixedPrefixToNamespaceMap.put(prefix, 
prefixToNamespaceMap.get(prefix));
-                } else {
-                    for (Map.Entry<String, String> entry : 
encodedNamespaceToPrefixMap.entrySet()) {
-                        if (entry.getValue().equals(prefix)) {
-                            fixedRegisteredPrefixesList.add(prefix);
-                            fixedPrefixToNamespaceMap.put(prefix, 
Text.unescape(entry.getKey()));
-                            break;
-                        }
-                    }
-                }
-            }
-            List<String> fixedRegisteredNamespacesEncodedList = new 
ArrayList<>();
-            HashMap<String, String> fixedNamespaceToPrefixMap = new 
HashMap<>();
-            for (String encodedNamespace : allNamespacesEncoded) {
-                if (mappedNamespacesEncoded.contains(encodedNamespace)) {
-                    fixedRegisteredNamespacesEncodedList.add(encodedNamespace);
-                    fixedNamespaceToPrefixMap.put(encodedNamespace, 
encodedNamespaceToPrefixMap.get(encodedNamespace));
-                } else {
-                    for (Map.Entry<String, String> entry : 
prefixToNamespaceMap.entrySet()) {
-                        if 
(Namespaces.encodeUri(entry.getValue()).equals(encodedNamespace)) {
-                            
fixedRegisteredNamespacesEncodedList.add(encodedNamespace);
-                            fixedNamespaceToPrefixMap.put(encodedNamespace, 
entry.getKey());
-                            break;
-                        }
-                    }
-                }
-            }
-            return new NamespaceRegistryModel(fixedRegisteredPrefixesList, 
fixedRegisteredNamespacesEncodedList,
-                    fixedPrefixToNamespaceMap, fixedNamespaceToPrefixMap);
-        }
-        return this;
-    }
-
-    /**
-     * Applies this namespace registry model to the given repository {@link 
Root}.
-     *
-     * @param root the root of the repository
-     * @throws RepositoryException if an error occurs while applying the 
changes
-     * @throws CommitFailedException if the commit fails
-     */
-    public void apply(Root root) throws RepositoryException, 
CommitFailedException {
-        Tree rootTree = root.getTree("/");
-        Tree namespaces = rootTree.getChild( JcrConstants.JCR_SYSTEM 
).getChild(REP_NAMESPACES);
-        Tree nsdata = namespaces.getChild(NamespaceConstants.REP_NSDATA);
-        for (PropertyState propertyState : namespaces.getProperties()) {
-            String name = propertyState.getName();
-            if (!JCR_PRIMARYTYPE.equals(name)) {
-                namespaces.removeProperty(name);
-            }
-        }
-        for (PropertyState propertyState : nsdata.getProperties()) {
-            String name = propertyState.getName();
-            if (!JCR_PRIMARYTYPE.equals(name)) {
-                nsdata.removeProperty(name);
-            }
-        }
-        nsdata.removeProperty(NamespaceConstants.REP_PREFIXES);
-        nsdata.removeProperty(NamespaceConstants.REP_URIS);
-        for (Map.Entry<String, String> entry : 
prefixToNamespaceMap.entrySet()) {
-            String prefix = entry.getKey();
-            String uri = entry.getValue();
-            namespaces.setProperty(prefix, uri);
-        }
-        for (Map.Entry<String, String> entry : 
encodedNamespaceToPrefixMap.entrySet()) {
-            String encodedUri = entry.getKey();
-            String prefix = entry.getValue();
-            nsdata.setProperty(encodedUri, prefix);
-        }
-        nsdata.setProperty(NamespaceConstants.REP_PREFIXES, mappedPrefixes, 
STRINGS);
-        nsdata.setProperty(NamespaceConstants.REP_URIS, 
prefixToNamespaceMap.values(), STRINGS);
-        if (!consistent) {
-            throw new IllegalStateException("Final registry consistency check 
failed.");
-        }
-    }
-
-    public boolean isConsistent() {
-        return consistent;
-    }
-
-    public boolean isFixable() {
-        return fixable;
-    }
-
-    /** Prefixes that are registered, but not mapped to or from a namespace 
uri.
-     * This kind of inconsistency cannot be fixed automatically, because the 
namespace uri
-     * corresponding to the prefix is unknown.
-     * Apply the {@link #setMappings(Map)} method to create a new model with 
the missing mappings.
-     */
-    public Set<String> getDanglingPrefixes() {
-        return danglingPrefixes;
-    }
-
-    /** Namespace uris that are registered, but not mapped to or from a prefix.
-     * This kind of inconsistency cannot be fixed automatically, because the 
prefix
-     * corresponding to the namespace uri is unknown.
-     * Apply the {@link #setMappings(Map)} method to create a new model with 
the missing mappings.
-     */
-    public Set<String> getDanglingEncodedNamespaceUris() {
-        return danglingNamespacesEncoded;
-    }
-
-    /**
-     * Broken mappings completed with the missing prefix or namespace uri.
-     */
-    public Map<String, String> getRepairedMappings() {
-        Map<String, String> map = new HashMap<>();
-        Set<String> repairablePrefixes = 
SetUtils.difference(SetUtils.difference(allPrefixes, consistentPrefixes), 
danglingPrefixes);
-        Set<String> repairableUrisEncoded = 
SetUtils.difference(SetUtils.difference(allNamespacesEncoded, 
consistentNamespacesEncoded), danglingNamespacesEncoded);
-        for (Map.Entry<String, String> entry : 
prefixToNamespaceMap.entrySet()) {
-            String prefix = entry.getKey();
-            String uri = entry.getValue();
-            if (repairablePrefixes.contains(prefix) || 
repairableUrisEncoded.contains(uri)) {
-                map.put(prefix, uri);
-            }
-        }
-        for (Map.Entry<String, String> entry : 
encodedNamespaceToPrefixMap.entrySet()) {
-            String prefix = entry.getValue();
-            String uri = entry.getKey();
-            if (repairablePrefixes.contains(prefix) || 
repairableUrisEncoded.contains(uri)) {
-                map.put(prefix, uri);
-            }
-        }
-        return map;
-    }
-
-    private <T> Set<T> findDuplicates(Collection<T> c) {
-        HashSet<T> uniques = new HashSet<>();
-        return c.stream().filter(t -> 
!uniques.add(t)).collect(Collectors.toSet());
-    }
-
-    /**
-     * Write a human-readable analysis of the namespace registry model to 
System.out.
-     */
-    public void dump() throws IOException {
-        dump(System.out);
-    }
-
-    /**
-     * Write a human-readable analysis of the namespace registry model to the
-     * given {@link OutputStream}.
-     *
-     * @param out the output stream to write to
-     * @throws IOException if an error occurs while writing to the output 
stream
-     */
-    public void dump(OutputStream out) throws IOException {
-        dump(new OutputStreamWriter(out, StandardCharsets.UTF_8));
-        out.flush();
-    }
-
-    public void dump(Writer out) throws IOException {
-        BufferedWriter writer = new BufferedWriter(out);
-            if (consistent) {
-                writer.write("This namespace registry model is consistent, 
containing the following mappings from prefixes to namespace uris:");
-                writer.newLine();
-                writer.newLine();
-                for (Map.Entry<String, String> entry : 
prefixToNamespaceMap.entrySet()) {
-                    writer.write(entry.getKey() + " -> " + entry.getValue());
-                    writer.newLine();
-                }
-            } else {
-                writer.write("This namespace registry model is inconsistent. 
The inconsistency can " + (isFixable()? "" : "NOT ") + "be fixed.");
-                writer.newLine();
-                writer.newLine();
-                writer.write("Registered prefixes without any namespace 
mapping: " + danglingPrefixes);
-                writer.newLine();
-                writer.write("Registered namespace URIs without any prefix 
mapping: " + danglingNamespacesEncoded);
-                writer.newLine();
-                writer.write("Duplicate prefixes: " + duplicatePrefixes);
-                writer.newLine();
-                writer.write("Duplicate namespace URIs: " + 
duplicateNamespacesEncoded);
-                writer.newLine();
-                writer.write("Mapped unregistered prefixes: " + 
SetUtils.difference(SetUtils.union(mappedPrefixes, mappedToPrefixes), 
registeredPrefixes));
-                writer.newLine();
-                writer.write("Mapped unregistered namespace URIs: " + 
SetUtils.difference(SetUtils.union(mappedNamespacesEncoded, 
mappedToNamespacesEncoded), registeredNamespacesEncoded));
-                writer.newLine();
-                writer.write("Mapped prefixes without a reverse mapping: " + 
SetUtils.difference(mappedPrefixes, mappedToPrefixes));
-                writer.newLine();
-                writer.write("Mapped namespace URIs without a reverse mapping: 
" + SetUtils.difference(mappedNamespacesEncoded, mappedToNamespacesEncoded));
-                writer.newLine();
-                writer.newLine();
-                if (isFixable()) {
-                    NamespaceRegistryModel repaired = tryRegistryRepair();
-                    writer.newLine();
-                    writer.write("The following mappings could be repaired:");
-                    writer.newLine();
-                    writer.newLine();
-                    for (Map.Entry<String, String> entry : 
getRepairedMappings().entrySet()) {
-                        writer.write(entry.getKey() + " -> " + 
entry.getValue());
-                        writer.newLine();
-                    }
-                    writer.newLine();
-                    writer.newLine();
-                    writer.write("The repaired registry would contain the 
following mappings:");
-                    writer.newLine();
-                    writer.newLine();
-                    for (Map.Entry<String, String> entry : 
repaired.prefixToNamespaceMap.entrySet()) {
-                        writer.write(entry.getKey() + " -> " + 
entry.getValue());
-                        writer.newLine();
-                    }
-                } else {
-                    writer.write("The following mappings could be repaired:");
-                    writer.newLine();
-                    writer.newLine();
-                    for (Map.Entry<String, String> entry : 
getRepairedMappings().entrySet()) {
-                        writer.write(entry.getKey() + " -> " + 
entry.getValue());
-                        writer.newLine();
-                    }
-                    writer.newLine();
-                    writer.newLine();
-                    writer.write("To create a fixed model, use 
#tryRegistryRepair(Map<String, String>) and supply missing prefix to namespace 
mappings as parameters");
-                    writer.newLine();
-                }
-            }
-            writer.flush();
-    }
-}
diff --git 
a/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/name/ReadOnlyNamespaceRegistry.java
 
b/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/name/ReadOnlyNamespaceRegistry.java
index 63dce06a57..ddf6509ce0 100644
--- 
a/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/name/ReadOnlyNamespaceRegistry.java
+++ 
b/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/name/ReadOnlyNamespaceRegistry.java
@@ -25,6 +25,7 @@ import javax.jcr.NamespaceRegistry;
 import javax.jcr.RepositoryException;
 import javax.jcr.UnsupportedRepositoryOperationException;
 
+import org.apache.jackrabbit.util.Text;
 import org.apache.jackrabbit.oak.api.PropertyState;
 import org.apache.jackrabbit.oak.api.Root;
 import org.apache.jackrabbit.oak.api.Tree;
@@ -34,7 +35,9 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.List;
+import java.util.stream.Collectors;
 
 /**
  * Read-only namespace registry. Used mostly internally when access to the
@@ -57,7 +60,7 @@ public class ReadOnlyNamespaceRegistry
         this.namespaces = root.getTree(NAMESPACES_PATH);
         this.nsdata = namespaces.getChild(REP_NSDATA);
         if (!CONSISTENCY_CHECKED) {
-            checkConsistency(root);
+            checkConsistency();
         }
     }
 
@@ -127,16 +130,56 @@ public class ReadOnlyNamespaceRegistry
                 "No namespace prefix registered for URI " + uri);
     }
 
-    public boolean checkConsistency(Root root) throws IllegalStateException {
-        NamespaceRegistryModel model = createNamespaceRegistryModel(root);
-        if (model == null) {
-            LOG.warn("Consistency check skipped because there is no namespace 
registry.");
+    protected void checkConsistency() {
+        final String jcrPrimaryType = "jcr:primaryType";
+        List<String> prefixes = Arrays.asList(getPrefixes());
+        List<String> encodedUris = 
Arrays.stream(getURIs()).map(Namespaces::encodeUri).collect(Collectors.toList());
+        if (prefixes.size() != encodedUris.size()) {
+            LOG.error("The namespace registry is inconsistent: found {} 
registered namespace prefixes and {} registered namespace URIs. The numbers 
have to be equal.", prefixes.size(), encodedUris.size());
         }
-        return model == null || model.isConsistent();
-    }
-
-    public NamespaceRegistryModel createNamespaceRegistryModel(Root root) {
-        return NamespaceRegistryModel.create(root);
+        int mappedPrefixCount = 0;
+        for (PropertyState propertyState : namespaces.getProperties()) {
+            String prefix = propertyState.getName();
+            if (!prefix.equals(jcrPrimaryType)) {
+                mappedPrefixCount++;
+                if (!prefixes.contains(prefix)) {
+                    LOG.error("The namespace registry is inconsistent: 
namespace prefix {} is mapped to a namespace URI, but not contained in the list 
of registered namespace prefixes.", prefix);
+                }
+                try {
+                    getURI(prefix);
+                } catch (NamespaceException e) {
+                    LOG.error("The namespace registry is inconsistent: 
namespace prefix {} is not mapped to a namespace URI.", prefix);
+                }
+            }
+        }
+        //prefixes contains the unmapped empty prefix
+        if (mappedPrefixCount + 1 != prefixes.size()) {
+            LOG.error("The namespace registry is inconsistent: found {} mapped 
namespace prefixes and {} registered namespace prefixes. The numbers have to be 
equal.", mappedPrefixCount, prefixes.size());
+        }
+        int mappedUriCount = 0;
+        for (PropertyState propertyState : nsdata.getProperties()) {
+            String encodedUri = propertyState.getName();
+            switch (encodedUri) {
+                case REP_PREFIXES:
+                case REP_URIS:
+                case jcrPrimaryType:
+                    break;
+                default:
+                    mappedUriCount++;
+                    if (!encodedUris.contains(encodedUri)) {
+                        LOG.error("The namespace registry is inconsistent: 
encoded namespace URI {} is mapped to a namespace prefix, but not contained in 
the list of registered namespace URIs.", encodedUri);
+                    }
+                    try {
+                        getPrefix(Text.unescapeIllegalJcrChars(encodedUri));
+                    } catch (NamespaceException e) {
+                        LOG.error("The namespace registry is inconsistent: 
namespace URI {} is not mapped to a namespace prefix.", encodedUri);
+                    }
+            }
+        }
+        //encodedUris contains the unmapped empty namespace URI
+        if (mappedUriCount + 1 != encodedUris.size()) {
+            LOG.error("The namespace registry is inconsistent: found {} mapped 
namespace URIs and {} registered namespace URIs. The numbers have to be 
equal.", mappedUriCount, encodedUris.size());
+        }
+        CONSISTENCY_CHECKED = true;
     }
-
 }
diff --git 
a/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/name/NamespaceRegistryTest.java
 
b/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/name/NamespaceRegistryTest.java
deleted file mode 100755
index d49bdcd46d..0000000000
--- 
a/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/name/NamespaceRegistryTest.java
+++ /dev/null
@@ -1,263 +0,0 @@
-/*
- * 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.name;
-
-import org.apache.jackrabbit.oak.InitialContent;
-import org.apache.jackrabbit.oak.Oak;
-import org.apache.jackrabbit.oak.api.ContentSession;
-import org.apache.jackrabbit.oak.api.PropertyState;
-import org.apache.jackrabbit.oak.api.Root;
-import org.apache.jackrabbit.oak.api.Tree;
-import org.apache.jackrabbit.oak.api.Type;
-import org.apache.jackrabbit.oak.plugins.memory.PropertyBuilder;
-import org.apache.jackrabbit.oak.spi.security.OpenSecurityProvider;
-
-import org.junit.Test;
-
-import java.io.ByteArrayOutputStream;
-import java.nio.charset.StandardCharsets;
-import java.util.Collections;
-import java.util.HashMap;
-
-import static 
org.apache.jackrabbit.oak.spi.namespace.NamespaceConstants.REP_NSDATA;
-import static 
org.apache.jackrabbit.oak.spi.namespace.NamespaceConstants.REP_PREFIXES;
-import static 
org.apache.jackrabbit.oak.spi.namespace.NamespaceConstants.REP_URIS;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-
-public class NamespaceRegistryTest {
-
-    /**
-     * Artificially apply inconsistencies to the namespace registry and test 
if the NamespaceRegistryModel
-     * handles them correctly.
-     * @throws Exception
-     */
-    @Test
-    public void testNamespaceRegistryModel() throws Exception {
-        try (ContentSession session = new Oak()
-                .with(new OpenSecurityProvider())
-                .with(new InitialContent())
-                .with(new NamespaceEditorProvider())
-                .createContentSession()) {
-            Root root = session.getLatestRoot();
-            ReadWriteNamespaceRegistry registry = new 
ReadWriteNamespaceRegistry(root) {
-                @Override
-                protected Root getWriteRoot() {
-                    return session.getLatestRoot();
-                }
-                @Override
-                protected void refresh() {
-                    root.refresh();
-                }
-            };
-            Tree namespaces = root.getTree("/jcr:system/rep:namespaces");
-            Tree nsdata = namespaces.getChild(REP_NSDATA);
-            PropertyState prefixProp = nsdata.getProperty(REP_PREFIXES);
-            PropertyState namespaceProp = nsdata.getProperty(REP_URIS);
-
-            // Check the initial state of the namespace registry
-            assertTrue(registry.checkConsistency(root));
-            NamespaceRegistryModel model = 
registry.createNamespaceRegistryModel(root);
-            assertTrue(model.isConsistent());
-            assertTrue(model.isFixable());
-
-            assertEquals(0, model.getDanglingPrefixes().size());
-            assertEquals(0, model.getDanglingEncodedNamespaceUris().size());
-            assertEquals(0, model.getRepairedMappings().size());
-
-            ByteArrayOutputStream out = new ByteArrayOutputStream();
-            model.dump(out);
-            String dump = out.toString(StandardCharsets.UTF_8);
-            assertTrue(dump.contains("This namespace registry model is 
consistent"));
-
-            // Add a registered prefix without any mapping
-            PropertyBuilder<String> builder = 
PropertyBuilder.copy(Type.STRING, prefixProp);
-            builder.addValue("foo");
-            nsdata.setProperty(builder.getPropertyState());
-
-            // Now it cannot be fixed automatically
-            assertFalse(registry.checkConsistency(root));
-            model = registry.createNamespaceRegistryModel(root);
-            assertFalse(model.isConsistent());
-            assertFalse(model.isFixable());
-
-            assertEquals(1, model.getDanglingPrefixes().size());
-            assertEquals(0, model.getDanglingEncodedNamespaceUris().size());
-            assertEquals(0, model.getRepairedMappings().size());
-
-            assertFalse(model.isConsistent());
-            out = new ByteArrayOutputStream();
-            model.dump(out);
-            assertFalse(model.isConsistent());
-            dump = out.toString(StandardCharsets.UTF_8);
-            assertFalse(model.isConsistent());
-            assertTrue(dump.contains("This namespace registry model is 
inconsistent. The inconsistency can NOT be fixed."));
-            assertFalse(model.isConsistent());
-
-            model = model.tryRegistryRepair();
-            assertFalse(model.isConsistent());
-            assertFalse(model.isFixable());
-
-            out = new ByteArrayOutputStream();
-            model.dump(out);
-            dump = out.toString(StandardCharsets.UTF_8);
-            assertTrue(dump.contains("This namespace registry model is 
inconsistent. The inconsistency can NOT be fixed."));
-
-            // Now add a mapping to a namespace uri, but not the reverse 
mapping
-            namespaces.setProperty("foo", "urn:foo", Type.STRING);
-
-            // This is inconsistent, but can be fixed automatically
-            assertFalse(registry.checkConsistency(root));
-            model = registry.createNamespaceRegistryModel(root);
-            assertFalse(model.isConsistent());
-            assertTrue(model.isFixable());
-
-            assertEquals(0, model.getDanglingPrefixes().size());
-            assertEquals(0, model.getDanglingEncodedNamespaceUris().size());
-            assertEquals(1, model.getRepairedMappings().size());
-
-            out = new ByteArrayOutputStream();
-            model.dump(out);
-            dump = out.toString(StandardCharsets.UTF_8);
-            assertTrue(dump.contains("This namespace registry model is 
inconsistent. The inconsistency can be fixed."));
-
-            model = model.tryRegistryRepair();
-            assertTrue(model.isConsistent());
-            assertTrue(model.isFixable());
-
-            out = new ByteArrayOutputStream();
-            model.dump(out);
-            dump = out.toString(StandardCharsets.UTF_8);
-            assertTrue(dump.contains("This namespace registry model is 
consistent"));
-
-            // Add a registered namespace uri without any mapping
-            builder = PropertyBuilder.copy(Type.STRING, namespaceProp);
-            builder.addValue("urn:bar");
-            nsdata.setProperty(builder.getPropertyState());
-
-            // Now it again cannot be fixed automatically
-            assertFalse(registry.checkConsistency(root));
-            model = registry.createNamespaceRegistryModel(root);
-            assertFalse(model.isConsistent());
-            assertFalse(model.isFixable());
-
-            assertEquals(0, model.getDanglingPrefixes().size());
-            assertEquals(1, model.getDanglingEncodedNamespaceUris().size());
-            assertEquals(1, model.getRepairedMappings().size());
-
-            model = model.tryRegistryRepair();
-            assertFalse(model.isConsistent());
-            assertFalse(model.isFixable());
-
-            // Now add a reverse mapping to a prefix, but not the forward 
mapping
-            nsdata.setProperty("urn%3Abar", "bar", Type.STRING);
-
-            // Now it can be fixed automatically again
-            assertFalse(registry.checkConsistency(root));
-            model = registry.createNamespaceRegistryModel(root);
-            assertFalse(model.isConsistent());
-            assertTrue(model.isFixable());
-
-            assertEquals(0, model.getDanglingPrefixes().size());
-            assertEquals(0, model.getDanglingEncodedNamespaceUris().size());
-            assertEquals(2, model.getRepairedMappings().size());
-
-            model = model.tryRegistryRepair();
-            assertTrue(model.isConsistent());
-            assertTrue(model.isFixable());
-
-            // Double a registered prefix
-            builder = PropertyBuilder.copy(Type.STRING, prefixProp);
-            builder.addValue("foo");
-            nsdata.setProperty(builder.getPropertyState());
-
-            // Can still be fixed automatically
-            assertFalse(registry.checkConsistency(root));
-            model = registry.createNamespaceRegistryModel(root);
-            assertFalse(model.isConsistent());
-            assertTrue(model.isFixable());
-
-            assertEquals(0, model.getDanglingPrefixes().size());
-            assertEquals(0, model.getDanglingEncodedNamespaceUris().size());
-            assertEquals(2, model.getRepairedMappings().size());
-
-            model = model.tryRegistryRepair();
-            assertTrue(model.isConsistent());
-            assertTrue(model.isFixable());
-
-            // Double a registered namespace uri
-            builder = PropertyBuilder.copy(Type.STRING, namespaceProp);
-            builder.addValue("urn:bar");
-            nsdata.setProperty(builder.getPropertyState());
-
-            // Can still be fixed automatically
-            assertFalse(registry.checkConsistency(root));
-            model = registry.createNamespaceRegistryModel(root);
-            assertFalse(model.isConsistent());
-            assertTrue(model.isFixable());
-
-            assertEquals(0, model.getDanglingPrefixes().size());
-            assertEquals(0, model.getDanglingEncodedNamespaceUris().size());
-            assertEquals(2, model.getRepairedMappings().size());
-
-            // remap a prefix
-            model = model.setMappings(Collections.singletonMap("foo", 
"urn:foo2"));
-            assertFalse(model.isConsistent());
-            assertTrue(model.isFixable());
-
-            // Add a registered namespace uri without any mapping
-            builder = PropertyBuilder.copy(Type.STRING, namespaceProp);
-            builder.addValue("urn:bar2");
-            nsdata.setProperty(builder.getPropertyState());
-
-            // Cannot be fixed automatically
-            assertFalse(registry.checkConsistency(root));
-            model = registry.createNamespaceRegistryModel(root);
-            assertFalse(model.isConsistent());
-            assertFalse(model.isFixable());
-
-            // remap a prefix and map the new URI to make it fixable
-            HashMap<String, String> mappings = new HashMap<>();
-            mappings.put("foo", "urn:foo2");
-            mappings.put("bar2", "urn:bar2");
-            assertFalse(registry.checkConsistency(root));
-            model = model.setMappings(mappings);
-            assertFalse(model.isConsistent());
-            assertTrue(model.isFixable());
-
-            // Apply the fixed model
-            model = model.tryRegistryRepair();
-            assertTrue(model.isConsistent());
-            assertTrue(model.isFixable());
-            assertFalse(registry.checkConsistency(root));
-            model.apply(root);
-            assertTrue(registry.checkConsistency(root));
-            
assertTrue(registry.createNamespaceRegistryModel(root).isConsistent());
-
-            assertEquals(0, model.getDanglingPrefixes().size());
-            assertEquals(0, model.getDanglingEncodedNamespaceUris().size());
-            assertEquals(0, model.getRepairedMappings().size());
-
-            // Check the extra mappings
-            assertEquals("urn:foo2", registry.getURI("foo"));
-            assertEquals("foo", registry.getPrefix("urn:foo2"));
-            assertEquals("urn:bar2", registry.getURI("bar2"));
-            assertEquals("bar2", registry.getPrefix("urn:bar2"));
-        }
-    }
-}
diff --git 
a/oak-run/src/main/java/org/apache/jackrabbit/oak/run/AvailableModes.java 
b/oak-run/src/main/java/org/apache/jackrabbit/oak/run/AvailableModes.java
index 9ea6adf590..87a37a46a8 100644
--- a/oak-run/src/main/java/org/apache/jackrabbit/oak/run/AvailableModes.java
+++ b/oak-run/src/main/java/org/apache/jackrabbit/oak/run/AvailableModes.java
@@ -82,7 +82,6 @@ public final class AvailableModes {
         builder.put("server", new ServerCommand());
         builder.put("purge-index-versions", new 
LucenePurgeOldIndexVersionCommand());
         builder.put("create-test-garbage", new CreateGarbageCommand());
-        builder.put("namespace-registry", new NamespaceRegistryCommand());
 
         return Collections.unmodifiableMap(builder);
     }
diff --git 
a/oak-run/src/main/java/org/apache/jackrabbit/oak/run/NamespaceRegistryCommand.java
 
b/oak-run/src/main/java/org/apache/jackrabbit/oak/run/NamespaceRegistryCommand.java
deleted file mode 100755
index 106497cbc0..0000000000
--- 
a/oak-run/src/main/java/org/apache/jackrabbit/oak/run/NamespaceRegistryCommand.java
+++ /dev/null
@@ -1,169 +0,0 @@
-/*
- * 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.run;
-
-import joptsimple.OptionParser;
-import org.apache.jackrabbit.oak.Oak;
-import org.apache.jackrabbit.oak.api.ContentSession;
-import org.apache.jackrabbit.oak.api.Root;
-import org.apache.jackrabbit.oak.commons.pio.Closer;
-import org.apache.jackrabbit.oak.plugins.name.NamespaceRegistryModel;
-import org.apache.jackrabbit.oak.plugins.name.ReadWriteNamespaceRegistry;
-import org.apache.jackrabbit.oak.run.cli.CommonOptions;
-import org.apache.jackrabbit.oak.run.cli.NodeStoreFixture;
-import org.apache.jackrabbit.oak.run.cli.NodeStoreFixtureProvider;
-import org.apache.jackrabbit.oak.run.cli.Options;
-import org.apache.jackrabbit.oak.run.commons.Command;
-import org.apache.jackrabbit.oak.spi.security.OpenSecurityProvider;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import java.io.IOException;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-/**
- * Command to analyze and repair the namespace registry in an Oak repository 
({@link NamespaceRegistryModel}).
- * Possible options are: --analyse, --fix, and --mappings, which will execute 
corresponding operations on
- * the namespace registry.
- * <p>
- * --analyse executes an operation that will print the current consistency 
state of the namespace registry to
- * the console. If the namespace registry is inconsistent and fixable, it will 
also perform a dry run of the
- * --fix operation and print the result to the console.
- * <p>
- * --fix executes an operation that will attempt to repair an inconsistent the 
namespace registry.
- * <p>
- * --mappings is an option for both operations, allowing to specify additional 
namespace mappings in
- * the format "prefix=uri", which will be applied during the operation.
- */
-public class NamespaceRegistryCommand implements Command {
-
-    public static final String NAME = "namespace-registry";
-
-    private static final Logger LOG = 
LoggerFactory.getLogger(NamespaceRegistryCommand.class);
-    private static final String SUMMARY = "Provides commands to analyse the 
integrity of the namespace registry and repair it if necessary.";
-
-    private final OptionParser parser = new OptionParser();
-
-    @Override
-    public void execute(String... args) throws Exception {
-
-        Options opts = getOptions(args);
-        NamespaceRegistryOptions namespaceRegistryOpts = 
opts.getOptionBean(NamespaceRegistryOptions.class);
-
-        try (Closer closer = Utils.createCloserWithShutdownHook()) {
-
-            NodeStoreFixture fixture = NodeStoreFixtureProvider.create(opts);
-            closer.register(fixture);
-
-            if (!checkParameters(namespaceRegistryOpts, fixture)) {
-                return;
-            }
-            doExecute(fixture, namespaceRegistryOpts);
-        } catch (Throwable e) {
-            LOG.error("Error occurred while performing namespace registry 
operation", e);
-            e.printStackTrace(System.err);
-        }
-    }
-
-    Options getOptions(String... args) throws IOException {
-        Options opts = new Options();
-        opts.setCommandName(NAME);
-        opts.setSummary(SUMMARY);
-        opts.setConnectionString(CommonOptions.DEFAULT_CONNECTION_STRING);
-        opts.registerOptionsFactory(NamespaceRegistryOptions.FACTORY);
-        opts.parseAndConfigure(parser, args);
-        return opts;
-    }
-
-    private boolean checkParameters(NamespaceRegistryOptions 
namespaceRegistryOptions, NodeStoreFixture fixture)
-            throws IOException {
-        if (!namespaceRegistryOptions.anyActionSelected()) {
-            LOG.info("No actions specified");
-            parser.printHelpOn(System.out);
-            return false;
-        } else if (fixture.getStore() == null) {
-            LOG.info("No NodeStore specified");
-            parser.printHelpOn(System.out);
-            return false;
-        }
-        return true;
-    }
-
-    private void doExecute(NodeStoreFixture fixture, NamespaceRegistryOptions 
namespaceRegistryOptions)
-            throws Exception {
-
-        boolean analyse = namespaceRegistryOptions.analyse();
-        boolean fix = namespaceRegistryOptions.fix();
-        List<String> mappings = namespaceRegistryOptions.mappings();
-        Oak oak = new Oak(fixture.getStore()).with(new OpenSecurityProvider());
-        try (ContentSession contentSession = oak.createContentSession()) {
-            Root root = contentSession.getLatestRoot();
-            ReadWriteNamespaceRegistry namespaceRegistry = new 
ReadWriteNamespaceRegistry(root) {
-                @Override
-                protected Root getWriteRoot() {
-                    return root;
-                }
-            };
-            if (analyse || fix) {
-                NamespaceRegistryModel registryModel = 
namespaceRegistry.createNamespaceRegistryModel(root);
-                if (fix) {
-                    Map<String, String> additionalMappings = new HashMap<>();
-                    if (mappings != null) {
-                        for (String mapping : mappings) {
-                            String[] parts = mapping.split("=");
-                            if (parts.length != 2) {
-                                System.err.println("Invalid mapping: " + 
mapping);
-                                return;
-                            }
-                            additionalMappings.put(parts[0].trim(), 
parts[1].trim());
-                        }
-                    }
-                    registryModel = 
registryModel.setMappings(additionalMappings);
-                    if (registryModel.isConsistent() && 
additionalMappings.isEmpty()) {
-                        System.out.println("The namespace registry is already 
consistent. No action is required.");
-                    } else if (registryModel.isFixable()) {
-                        registryModel.dump(System.out);
-                        System.out.println();
-                        System.out.println("Now fixing the registry.");
-                        System.out.println();
-                        System.out.flush();
-                        NamespaceRegistryModel repaired = 
registryModel.tryRegistryRepair();
-                        if (repaired == null) {
-                            System.out.println("An unknown error has occurred. 
No changes have been made to the namespace registry.");
-                            return;
-                        }
-                        repaired.apply(root);
-                        root.commit();
-                        repaired.dump();
-                    } else {
-                        registryModel.dump();
-                    }
-                } else {
-                    if (registryModel == null) {
-                        System.out.println("There is no namespace registry in 
the repository.");
-                    } else {
-                        registryModel.dump();
-                    }
-                }
-            } else {
-                System.err.println("No action specified. Use --analyse to 
check the integrity of the namespace registry. Use --fix to repair it if 
necessary and possible.");
-            }
-        }
-    }
-}
diff --git 
a/oak-run/src/main/java/org/apache/jackrabbit/oak/run/NamespaceRegistryOptions.java
 
b/oak-run/src/main/java/org/apache/jackrabbit/oak/run/NamespaceRegistryOptions.java
deleted file mode 100755
index 49b5d8f357..0000000000
--- 
a/oak-run/src/main/java/org/apache/jackrabbit/oak/run/NamespaceRegistryOptions.java
+++ /dev/null
@@ -1,104 +0,0 @@
-/*
- * 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.run;
-
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-
-import joptsimple.OptionParser;
-import joptsimple.OptionSet;
-import joptsimple.OptionSpec;
-import org.apache.jackrabbit.oak.run.cli.OptionsBean;
-import org.apache.jackrabbit.oak.run.cli.OptionsBeanFactory;
-
-public class NamespaceRegistryOptions implements OptionsBean {
-
-    public static final OptionsBeanFactory FACTORY = 
NamespaceRegistryOptions::new;
-
-    private OptionSet options;
-    private final Set<OptionSpec<Void>> actionOpts;
-    private final Set<String> operationNames;
-
-    private final OptionSpec<Void> analyseOpt;
-    private final OptionSpec<Void> fixOpt;
-    private final OptionSpec<String> mappingsOpt;
-
-    public NamespaceRegistryOptions(OptionParser parser) {
-        analyseOpt = parser.accepts("analyse", "List the prefix to namespace 
map and check for consistency.");
-        fixOpt = parser.accepts("fix", "List the prefix to namespace map, 
check for consistency and fix any inconsistencies, if possible.");
-        mappingsOpt = parser.accepts("mappings", "Optionally specify explicit 
prefix to namespace mappings ad a list of prefix=uri 
expressions").withRequiredArg();
-        actionOpts = Set.of(analyseOpt, fixOpt);
-        operationNames = collectionOperationNames(actionOpts);
-    }
-
-    @Override
-    public void configure(OptionSet options) {
-        this.options = options;
-    }
-
-    @Override
-    public String title() {
-        return "";
-    }
-
-    @Override
-    public String description() {
-        return "The namespace-registry command supports the following 
operations.";
-    }
-
-    @Override
-    public int order() {
-        return Integer.MAX_VALUE;
-    }
-
-    @Override
-    public Set<String> operationNames() {
-        return operationNames;
-    }
-
-    public boolean anyActionSelected() {
-        for (OptionSpec<Void> spec : actionOpts) {
-            if (options.has(spec)){
-                return true;
-            }
-        }
-        return false;
-    }
-
-    public boolean analyse() {
-        return  options.has(analyseOpt);
-    }
-
-    public boolean fix() {
-        return  options.has(fixOpt);
-    }
-
-    public List<String> mappings() {
-        return  options.valuesOf(mappingsOpt);
-    }
-
-    private static Set<String> collectionOperationNames(Set<OptionSpec<Void>> 
actionOpts) {
-        Set<String> result = new HashSet<>();
-        for (OptionSpec<Void> spec : actionOpts){
-            result.addAll(spec.options());
-        }
-        return result;
-    }
-}
diff --git 
a/oak-run/src/test/java/org/apache/jackrabbit/oak/run/NamespaceRegistryCommandTest.java
 
b/oak-run/src/test/java/org/apache/jackrabbit/oak/run/NamespaceRegistryCommandTest.java
deleted file mode 100755
index 89d0ed2d73..0000000000
--- 
a/oak-run/src/test/java/org/apache/jackrabbit/oak/run/NamespaceRegistryCommandTest.java
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
- * 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.run;
-
-import org.apache.jackrabbit.JcrConstants;
-import org.apache.jackrabbit.oak.InitialContent;
-import org.apache.jackrabbit.oak.api.CommitFailedException;
-import org.apache.jackrabbit.oak.plugins.document.DocumentNodeStore;
-import org.apache.jackrabbit.oak.plugins.document.MongoUtils;
-import org.apache.jackrabbit.oak.plugins.name.Namespaces;
-import org.apache.jackrabbit.oak.run.cli.NodeStoreFixture;
-import org.apache.jackrabbit.oak.run.cli.NodeStoreFixtureProvider;
-import org.apache.jackrabbit.oak.spi.commit.CommitInfo;
-import org.apache.jackrabbit.oak.spi.commit.EmptyHook;
-import org.apache.jackrabbit.oak.spi.namespace.NamespaceConstants;
-import org.apache.jackrabbit.oak.spi.state.NodeBuilder;
-import org.junit.Before;
-import org.junit.Test;
-
-import java.io.ByteArrayOutputStream;
-import java.io.PrintStream;
-import java.nio.charset.StandardCharsets;
-
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assume.assumeTrue;
-
-/**
- * Tests for the {@link NamespaceRegistryCommand}.
- */
-public class NamespaceRegistryCommandTest {
-
-    private final NamespaceRegistryCommand cmd = new 
NamespaceRegistryCommand();
-    private DocumentNodeStore store;
-
-    @Before
-    public void before() throws CommitFailedException {
-        assumeTrue(MongoUtils.isAvailable());
-        try {
-            NodeStoreFixture fixture = 
NodeStoreFixtureProvider.create(cmd.getOptions(MongoUtils.URL, "--fix", 
"--read-write"));
-            store = (DocumentNodeStore) fixture.getStore();
-        } catch (Exception e) {
-            throw new RuntimeException(e);
-        }
-        NodeBuilder rootBuilder = store.getRoot().builder();
-        new InitialContent().initialize(rootBuilder);
-        NodeBuilder system = rootBuilder.getChildNode(JcrConstants.JCR_SYSTEM);
-        NodeBuilder namespaces = 
system.getChildNode(NamespaceConstants.REP_NAMESPACES);
-        namespaces.remove();
-        
Namespaces.setupNamespaces(rootBuilder.getChildNode(JcrConstants.JCR_SYSTEM));
-        store.merge(rootBuilder, EmptyHook.INSTANCE, CommitInfo.EMPTY);
-        store.runBackgroundOperations();
-    }
-
-    @Test
-    public void analyse() throws Exception {
-        testCmd(new String[] { MongoUtils.URL, "--analyse" }, new String[] { 
"This namespace registry model is consistent, containing the following mappings 
from prefixes to namespace uris:" });
-    }
-
-    @Test
-    public void fix() throws Exception {
-        testCmd(new String[] { MongoUtils.URL, "--fix" }, new String[] { "The 
namespace registry is already consistent. No action is required." });
-    }
-
-    @Test
-    public void breakAndFix() throws Exception {
-        NodeBuilder rootBuilder = store.getRoot().builder();
-        NodeBuilder namespaces = 
rootBuilder.getChildNode(JcrConstants.JCR_SYSTEM).getChildNode(NamespaceConstants.REP_NAMESPACES);
-        namespaces.setProperty("foo", "urn:foo");
-        store.merge(rootBuilder, EmptyHook.INSTANCE, CommitInfo.EMPTY);
-        store.runBackgroundOperations();
-        testCmd(new String[] { MongoUtils.URL, "--analyse" }, new String[] { 
"This namespace registry model is inconsistent. The inconsistency can be 
fixed.", "The repaired registry would contain the following mappings:", "foo -> 
urn:foo" });
-        testCmd(new String[] { MongoUtils.URL, "--fix", "--read-write" }, new 
String[] { "This namespace registry model is consistent, containing the 
following mappings from prefixes to namespace uris:", "foo -> urn:foo" });
-    }
-
-    @Test
-    public void mappings() throws Exception {
-        testCmd(new String[] { MongoUtils.URL, "--analyse" }, new String[] { 
"This namespace registry model is consistent"});
-        testCmd(new String[] { MongoUtils.URL, "--fix", "--mappings",  
"foo=urn:foo", "--read-write" }, new String[] { "This namespace registry model 
is consistent, containing the following mappings from prefixes to namespace 
uris:", "foo -> urn:foo" });
-    }
-
-    private void testCmd(String[] opts, String[] output) throws Exception {
-        ByteArrayOutputStream out = new ByteArrayOutputStream();
-        try(PrintStream printStream = new PrintStream(out)) {
-            System.setOut(printStream);
-            cmd.execute(opts);
-            printStream.flush();
-            for (String expected : output) {
-                String s = out.toString(StandardCharsets.UTF_8);
-                assertTrue(s.contains(expected));
-            }
-        }
-    }
-}

Reply via email to