All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.apache.jackrabbit.oak.namepath.impl.GlobalNameMapper Maven / Gradle / Ivy

There is a newer version: 2024.11.18751.20241128T090041Z-241100
Show newest version
/*
 * 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.namepath.impl;

import static org.apache.jackrabbit.guava.common.base.Preconditions.checkArgument;
import static java.util.Collections.emptyList;
import static java.util.Collections.emptyMap;
import static java.util.Objects.requireNonNull;
import static org.apache.jackrabbit.oak.api.Type.STRINGS;
import static org.apache.jackrabbit.oak.plugins.memory.EmptyNodeState.EMPTY_NODE;
import static org.apache.jackrabbit.oak.spi.namespace.NamespaceConstants.NAMESPACES_PATH;
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.apache.jackrabbit.oak.plugins.name.Namespaces.encodeUri;
import static org.apache.jackrabbit.oak.plugins.tree.factories.RootFactory.createReadOnlyRoot;
import static org.apache.jackrabbit.oak.plugins.tree.factories.TreeFactory.createReadOnlyTree;
import static org.apache.jackrabbit.oak.plugins.tree.TreeUtil.getString;
import static org.apache.jackrabbit.oak.plugins.tree.TreeUtil.getStrings;

import java.util.Map;
import java.util.Map.Entry;

import javax.jcr.RepositoryException;

import org.apache.jackrabbit.oak.api.Root;
import org.apache.jackrabbit.oak.api.Tree;
import org.apache.jackrabbit.oak.namepath.NameMapper;
import org.apache.jackrabbit.oak.spi.state.NodeBuilder;
import org.apache.jackrabbit.oak.spi.state.NodeState;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

/**
 * Name mapper with no local prefix remappings. URI to prefix mappings
 * are read from the repository when for transforming expanded JCR names
 * to prefixed Oak names.
 * 

* Note that even though this class could be used to verify that all prefixed * names have valid prefixes, we explicitly don't do that since this is a * fairly performance-sensitive part of the codebase and since normally the * NameValidator and other consistency checks already ensure that all names * being committed or already in the repository should be valid. A separate * consistency check can be used if needed to locate and fix any Oak names * with invalid namespace prefixes. */ public class GlobalNameMapper implements NameMapper { protected static boolean isHiddenName(String name) { return name.startsWith(":"); } protected static boolean isExpandedName(String name) { if (name.startsWith("{")) { int brace = name.indexOf('}', 1); return brace != -1 && name.substring(1, brace).indexOf(':') != -1; } else { return false; } } private final Root root; private Tree namespaces; private Tree nsdata; public GlobalNameMapper(Root root) { this.root = root; init(); } public GlobalNameMapper(NodeState root) { this(createReadOnlyRoot(root)); } private void init() { if (root != null) { this.namespaces = root.getTree(NAMESPACES_PATH); this.nsdata = namespaces.getChild(REP_NSDATA); } } public GlobalNameMapper(Map mappings) { NodeBuilder forward = EMPTY_NODE.builder(); NodeBuilder reverse = EMPTY_NODE.builder(); for (Entry entry : mappings.entrySet()) { String prefix = entry.getKey(); if (!prefix.isEmpty()) { String uri = entry.getValue(); forward.setProperty(prefix, uri); reverse.setProperty(encodeUri(uri), prefix); } } reverse.setProperty(REP_PREFIXES, mappings.keySet(), STRINGS); reverse.setProperty(REP_URIS, mappings.values(), STRINGS); this.root = null; this.namespaces = createReadOnlyTree(forward.getNodeState()); this.nsdata = createReadOnlyTree(reverse.getNodeState()); } @Override @NotNull public String getJcrName(@NotNull String oakName) { // Sanity checks, can be turned to assertions if needed for performance requireNonNull(oakName); checkArgument(!isHiddenName(oakName), oakName); checkArgument(!isExpandedName(oakName), oakName); return oakName; } @Override @Nullable public String getOakNameOrNull(@NotNull String jcrName) { if (jcrName.startsWith("{")) { return getOakNameFromExpanded(jcrName); } return jcrName; } @Override @NotNull public String getOakName(@NotNull String jcrName) throws RepositoryException { String oakName = getOakNameOrNull(jcrName); if (oakName == null) { throw new RepositoryException("Invalid jcr name " + jcrName); } return oakName; } @NotNull @Override public Map getSessionLocalMappings() { return emptyMap(); } @Nullable protected String getOakNameFromExpanded(String expandedName) { checkArgument(expandedName.startsWith("{")); int brace = expandedName.indexOf('}', 1); if (brace > 0) { String uri = expandedName.substring(1, brace); if (uri.isEmpty()) { return expandedName.substring(2); // special case: {}name } else if (uri.indexOf(':') != -1) { // It's an expanded name, look up the namespace prefix String oakPrefix = getOakPrefixOrNull(uri); if (oakPrefix != null) { return oakPrefix + ':' + expandedName.substring(brace + 1); } else { return null; // no matching namespace prefix } } } return expandedName; // not an expanded name } @Nullable protected synchronized String getOakPrefixOrNull(String uri) { if (uri.isEmpty()) { return uri; } return getNsData(encodeUri(uri)); } @Nullable protected synchronized String getOakURIOrNull(String prefix) { if (prefix.isEmpty()) { return prefix; } return getNamespacesProperty(prefix); } protected String getNamespacesProperty(String prefix) { return getString(namespaces, prefix); } private String getNsData(String uri) { return getString(nsdata, uri); } protected Iterable getPrefixes() { Iterable prefs = getStrings(nsdata, REP_PREFIXES); if (prefs != null) { return prefs; } else { return emptyList(); } } public void onSessionRefresh() { init(); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy