org.openrdf.repository.object.managers.helpers.RoleMatcher Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of alibaba-composition-object Show documentation
Show all versions of alibaba-composition-object Show documentation
The Object Composition library merges multiple Java objects into a single multi-subject object.
/*
* Copyright (c) 2009, James Leigh All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* - Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* - Neither the name of the openrdf.org nor the names of its contributors may
* be used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
package org.openrdf.repository.object.managers.helpers;
import java.util.Collection;
import java.util.Comparator;
import java.util.Map;
import java.util.NavigableMap;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.ConcurrentNavigableMap;
import java.util.concurrent.ConcurrentSkipListMap;
import java.util.concurrent.CopyOnWriteArrayList;
/**
* Matches concepts with @matches annotation to URIs as their are loaded from
* the repository.
*/
public class RoleMatcher implements Cloneable {
private Comparator reverse = new Comparator() {
public int compare(String o1, String o2) {
int i = o1.length();
int j = o2.length();
while (i > 0 && j > 0) {
char c1 = o1.charAt(--i);
char c2 = o2.charAt(--j);
if (c1 != c2) {
return c1 - c2;
}
}
return i - j;
}
};
private ConcurrentNavigableMap>>> hostsufPathpre = new ConcurrentSkipListMap(reverse);
private ConcurrentNavigableMap>>> hostsufPath = new ConcurrentSkipListMap(reverse);
private ConcurrentNavigableMap>> uriprefix = new ConcurrentSkipListMap();
private ConcurrentMap>> uris = new ConcurrentHashMap();
private boolean empty = true;
public RoleMatcher clone() {
RoleMatcher cloned = new RoleMatcher();
for (String host : hostsufPathpre.keySet()) {
for (String path : hostsufPathpre.get(host).keySet()) {
for (Class> role : hostsufPathpre.get(host).get(path)) {
cloned.addRoles('*' + host + path + '*', role);
}
}
}
for (String host : hostsufPath.keySet()) {
for (String path : hostsufPath.get(host).keySet()) {
for (Class> role : hostsufPath.get(host).get(path)) {
cloned.addRoles('*' + host + path, role);
}
}
}
for (String key : uriprefix.keySet()) {
for (Class> role : uriprefix.get(key)) {
cloned.addRoles(key + '*', role);
}
}
for (String key : uris.keySet()) {
for (Class> role : uris.get(key)) {
cloned.addRoles(key, role);
}
}
return cloned;
}
public boolean isEmpty() {
return empty;
}
public void addRoles(String pattern, Class> role) {
if (pattern.endsWith("*")) {
String prefix = pattern.substring(0, pattern.length() - 1);
if (prefix.startsWith("/")) {
addPathPrefix(hostsufPathpre, "", prefix, role);
} else if (prefix.startsWith("*") && prefix.contains("/")) {
int idx = prefix.indexOf('/');
String suffix = prefix.substring(1, idx);
prefix = prefix.substring(idx);
addPathPrefix(hostsufPathpre, suffix, prefix, role);
} else if (prefix.startsWith("*")) {
String suffix = prefix.substring(1);
addPathPrefix(hostsufPathpre, suffix, "", role);
} else {
add(uriprefix, prefix, role);
}
} else {
if (pattern.startsWith("/")) {
addPath(hostsufPath, "", pattern, role);
} else if (pattern.startsWith("*") && pattern.contains("/")) {
int idx = pattern.indexOf('/');
String suffix = pattern.substring(1, idx);
pattern = pattern.substring(idx);
addPath(hostsufPath, suffix, pattern, role);
} else if (pattern.startsWith("*")) {
String suffix = pattern.substring(1);
addPath(hostsufPath, suffix, "", role);
} else {
add(uris, pattern, role);
}
}
empty = false;
}
public void findRoles(String uri, Collection> roles) {
findExactRoles(uris, uri, roles);
findRoles(uriprefix, uri, roles);
int idx = uri.indexOf("://") + 3;
if (idx > 3 && idx < uri.length()) {
int sidx = uri.indexOf('/', idx);
if (sidx > 0) {
String auth = uri.substring(idx, sidx);
String path = uri.substring(sidx);
findPathPrefixRoles(auth, path, roles);
findPathRoles(auth, path, roles);
} else {
String auth = uri.substring(idx);
findPathPrefixRoles(auth, "", roles);
findPathRoles(auth, "", roles);
}
}
}
private void addPathPrefix(
ConcurrentNavigableMap>>> map,
String suffix, String prefix, Class> role) {
ConcurrentNavigableMap>> m, o;
m = map.get(suffix);
if (m == null) {
m = new ConcurrentSkipListMap>>();
o = map.putIfAbsent(suffix, m);
if (o != null) {
m = o;
}
}
add(m, prefix, role);
}
private void addPath(
ConcurrentNavigableMap>>> map,
String suffix, String prefix, Class> role) {
ConcurrentMap>> m, o;
m = map.get(suffix);
if (m == null) {
m = new ConcurrentHashMap>>();
o = map.putIfAbsent(suffix, m);
if (o != null) {
m = o;
}
}
add(m, prefix, role);
}
private void add(ConcurrentMap>> map,
String pattern, Class> role) {
Collection> list = map.get(pattern);
if (list == null) {
list = new CopyOnWriteArrayList>();
Collection> o = map.putIfAbsent(pattern, list);
if (o != null) {
list = o;
}
}
if (!list.contains(role)) {
list.add(role);
}
}
private void findPathRoles(String auth, String path, Collection> roles) {
Map>> map = hostsufPath.get(auth);
if (map != null) {
findExactRoles(map, path, roles);
}
String key = hostsufPath.lowerKey(auth);
if (key == null) {
return;
} else if (auth.endsWith(key)) {
findPathRoles(key, path, roles);
} else if (auth.length() > 0) {
int i = auth.length() - 1;
int j = key.length() - 1;
while (i >= 0 && j >=0 && auth.charAt(i) == key.charAt(j)) {
i--;
j--;
}
String suffix = auth.substring(i + 1);
findPathRoles(suffix, path, roles);
}
}
private void findPathPrefixRoles(String auth, String path, Collection> roles) {
NavigableMap>> map = hostsufPathpre.get(auth);
if (map != null) {
findRoles(map, path, roles);
}
String key = hostsufPathpre.lowerKey(auth);
if (key == null) {
return;
} else if (auth.endsWith(key)) {
findPathPrefixRoles(key, path, roles);
} else if (auth.length() > 0) {
int i = auth.length() - 1;
int j = key.length() - 1;
while (i >= 0 && j >= 0 && auth.charAt(i) == key.charAt(j)) {
i--;
j--;
}
String suffix = auth.substring(i + 1);
findPathPrefixRoles(suffix, path, roles);
}
}
private void findRoles(NavigableMap>> map,
String full, Collection> roles) {
findExactRoles(map, full, roles);
String key = map.lowerKey(full);
if (key == null) {
return;
} else if (full.startsWith(key)) {
findRoles(map, key, roles);
} else if (full.length() > 0) {
int idx = 0;
while (idx < full.length() && idx < key.length()
&& full.charAt(idx) == key.charAt(idx)) {
idx++;
}
String prefix = full.substring(0, idx);
findRoles(map, prefix, roles);
}
}
private void findExactRoles(Map>> map,
String uri, Collection> roles) {
Collection> list = map.get(uri);
if (list != null) {
roles.addAll(list);
}
}
}