http://git-wip-us.apache.org/repos/asf/jena/blob/1320f8db/jena-base/src/main/java/org/apache/jena/atlas/lib/SetUtils.java ---------------------------------------------------------------------- diff --git a/jena-base/src/main/java/org/apache/jena/atlas/lib/SetUtils.java b/jena-base/src/main/java/org/apache/jena/atlas/lib/SetUtils.java new file mode 100644 index 0000000..f4e561d --- /dev/null +++ b/jena-base/src/main/java/org/apache/jena/atlas/lib/SetUtils.java @@ -0,0 +1,84 @@ +/* + * 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.jena.atlas.lib; + +import java.util.HashSet ; +import java.util.Set ; + +public class SetUtils +{ + private SetUtils() {} + + public static <X> Set<X> setOfOne(X element) { return DS.setOfOne(element) ; } + + // Set specific operations + + public static <T> Set<T> intersection(Set<? extends T> setLeft, Set<? extends T> setRight) + { + Set<T> results = new HashSet<>(setLeft) ; + results.retainAll(setRight) ; + return results ; + } + + public static <T> boolean intersectionP(Set<? extends T> s1, Set<? extends T> s2) + { + for( T elt : s1 ) + { + if ( s2.contains(elt) ) + return true ; + } + return false ; + } + + public static <T> Set<T> union(Set<? extends T> s1, Set<? extends T> s2) + { + Set<T> s3 = new HashSet<>(s1) ; + s3.addAll(s2) ; + return s3 ; + } + + /** Return is s1 \ s2 */ + + public static <T> Set<T> difference(Set<? extends T> s1, Set<? extends T> s2) + { + Set<T> s3 = new HashSet<>(s1) ; + s3.removeAll(s2) ; + return s3 ; + } + + /** Return true if s1 and s2 are disjoint */ + public static <T> boolean isDisjoint(Set<? extends T> s1, Set<? extends T> s2) + { + Set<? extends T> x = s1 ; + Set<? extends T> y = s2 ; + if ( s1.size() < s2.size() ) + { + x = s2 ; + y = s1 ; + } + + for ( T item : x ) + { + if ( y.contains(item)) + return false ; + } + return true ; + } +} +
http://git-wip-us.apache.org/repos/asf/jena/blob/1320f8db/jena-base/src/main/java/org/apache/jena/atlas/lib/Sink.java ---------------------------------------------------------------------- diff --git a/jena-base/src/main/java/org/apache/jena/atlas/lib/Sink.java b/jena-base/src/main/java/org/apache/jena/atlas/lib/Sink.java new file mode 100644 index 0000000..01bb809 --- /dev/null +++ b/jena-base/src/main/java/org/apache/jena/atlas/lib/Sink.java @@ -0,0 +1,29 @@ +/* + * 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.jena.atlas.lib; + + +/** Interface for the destination of things */ +public interface Sink<T> extends Closeable +{ + // Can't help but think it should be "Pipe" + // If Sync looses Sync(boolean), then make this "extends Sync" + void send(T item) ; + void flush() ; +} http://git-wip-us.apache.org/repos/asf/jena/blob/1320f8db/jena-base/src/main/java/org/apache/jena/atlas/lib/SinkCounting.java ---------------------------------------------------------------------- diff --git a/jena-base/src/main/java/org/apache/jena/atlas/lib/SinkCounting.java b/jena-base/src/main/java/org/apache/jena/atlas/lib/SinkCounting.java new file mode 100644 index 0000000..62c6e43 --- /dev/null +++ b/jena-base/src/main/java/org/apache/jena/atlas/lib/SinkCounting.java @@ -0,0 +1,41 @@ +/* + * 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.jena.atlas.lib; + + + +public final class SinkCounting<T> extends SinkWrapper<T> +{ + private long count = 0 ; + + public SinkCounting(Sink<T> output) + { super(output) ; } + + public SinkCounting() + { super(new SinkNull<T>()) ; } + + @Override + public void send(T thing) + { + count++ ; + super.send(thing) ; + } + + public long getCount() { return count ; } +} http://git-wip-us.apache.org/repos/asf/jena/blob/1320f8db/jena-base/src/main/java/org/apache/jena/atlas/lib/SinkLogging.java ---------------------------------------------------------------------- diff --git a/jena-base/src/main/java/org/apache/jena/atlas/lib/SinkLogging.java b/jena-base/src/main/java/org/apache/jena/atlas/lib/SinkLogging.java new file mode 100644 index 0000000..e6928de --- /dev/null +++ b/jena-base/src/main/java/org/apache/jena/atlas/lib/SinkLogging.java @@ -0,0 +1,41 @@ +/* + * 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.jena.atlas.lib; + +import org.slf4j.Logger ; + +public class SinkLogging<T> implements Sink<T> +{ + private Logger log ; + + public SinkLogging(Logger log) { this.log = log ; } + + @Override + public void send(T item) + { + log.info("Sink: "+item) ; + } + + @Override + public void flush() { } + + @Override + public void close() {} + +} http://git-wip-us.apache.org/repos/asf/jena/blob/1320f8db/jena-base/src/main/java/org/apache/jena/atlas/lib/SinkNull.java ---------------------------------------------------------------------- diff --git a/jena-base/src/main/java/org/apache/jena/atlas/lib/SinkNull.java b/jena-base/src/main/java/org/apache/jena/atlas/lib/SinkNull.java new file mode 100644 index 0000000..9242c97 --- /dev/null +++ b/jena-base/src/main/java/org/apache/jena/atlas/lib/SinkNull.java @@ -0,0 +1,33 @@ +/* + * 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.jena.atlas.lib; + + + +public class SinkNull<T> implements Sink<T> +{ + public static <X> SinkNull<X> create() { return new SinkNull<>() ; } + + /*@Override*/ @Override + public void send(T thing) {} + /*@Override*/ @Override + public void close() {} + /*@Override*/ @Override + public void flush() { } +} http://git-wip-us.apache.org/repos/asf/jena/blob/1320f8db/jena-base/src/main/java/org/apache/jena/atlas/lib/SinkPrint.java ---------------------------------------------------------------------- diff --git a/jena-base/src/main/java/org/apache/jena/atlas/lib/SinkPrint.java b/jena-base/src/main/java/org/apache/jena/atlas/lib/SinkPrint.java new file mode 100644 index 0000000..4fc694d --- /dev/null +++ b/jena-base/src/main/java/org/apache/jena/atlas/lib/SinkPrint.java @@ -0,0 +1,45 @@ +/* + * 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.jena.atlas.lib; + +import java.io.PrintStream ; + +public class SinkPrint<T> implements Sink<T> +{ + + private PrintStream out ; + + public SinkPrint() + { this(System.out); } + + public SinkPrint(PrintStream out) + { this.out = out ; } + + @Override + public void send(T item) + { + out.println("Sink: "+item) ; + } + + @Override + public void flush() { } + + @Override + public void close() {} +} http://git-wip-us.apache.org/repos/asf/jena/blob/1320f8db/jena-base/src/main/java/org/apache/jena/atlas/lib/SinkSplit.java ---------------------------------------------------------------------- diff --git a/jena-base/src/main/java/org/apache/jena/atlas/lib/SinkSplit.java b/jena-base/src/main/java/org/apache/jena/atlas/lib/SinkSplit.java new file mode 100644 index 0000000..8d50ee4 --- /dev/null +++ b/jena-base/src/main/java/org/apache/jena/atlas/lib/SinkSplit.java @@ -0,0 +1,55 @@ +/* + * 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.jena.atlas.lib; + +/** Split a sink stream and duplicate the operations onto two sinks + * See also: {@link SinkWrapper} + */ +public class SinkSplit<T> implements Sink<T> +{ + private final Sink<T> sink1 ; + private final Sink<T> sink2 ; + + public SinkSplit(Sink<T> sink1, Sink<T> sink2) + { + this.sink1 = sink1 ; + this.sink2 = sink2 ; + } + + @Override + public void flush() + { + sink1.flush(); + sink2.flush(); + } + + @Override + public void send(T item) + { + sink1.send(item) ; + sink2.send(item) ; + } + + @Override + public void close() + { + sink1.close(); + sink2.close(); + } +} http://git-wip-us.apache.org/repos/asf/jena/blob/1320f8db/jena-base/src/main/java/org/apache/jena/atlas/lib/SinkToCollection.java ---------------------------------------------------------------------- diff --git a/jena-base/src/main/java/org/apache/jena/atlas/lib/SinkToCollection.java b/jena-base/src/main/java/org/apache/jena/atlas/lib/SinkToCollection.java new file mode 100644 index 0000000..d7e04ba --- /dev/null +++ b/jena-base/src/main/java/org/apache/jena/atlas/lib/SinkToCollection.java @@ -0,0 +1,38 @@ +/** + * 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.jena.atlas.lib; + +import java.util.Collection; + +/** Send items to a collection */ +public class SinkToCollection<T> implements Sink<T> +{ + private final Collection<T> c ; + + public SinkToCollection(Collection<T> c) { this.c = c ; } + + @Override + public void send(T item) { c.add(item); } + + @Override + public void flush() {} + + @Override + public void close() {} +} http://git-wip-us.apache.org/repos/asf/jena/blob/1320f8db/jena-base/src/main/java/org/apache/jena/atlas/lib/SinkToQueue.java ---------------------------------------------------------------------- diff --git a/jena-base/src/main/java/org/apache/jena/atlas/lib/SinkToQueue.java b/jena-base/src/main/java/org/apache/jena/atlas/lib/SinkToQueue.java new file mode 100644 index 0000000..f7e5dff --- /dev/null +++ b/jena-base/src/main/java/org/apache/jena/atlas/lib/SinkToQueue.java @@ -0,0 +1,52 @@ +/** + * 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.jena.atlas.lib; + +import java.util.concurrent.BlockingQueue ; +import java.util.concurrent.CancellationException ; + +/** Send items to a blocking queue */ +public class SinkToQueue<T> implements Sink<T> +{ + private final BlockingQueue<T> queue ; + + public SinkToQueue(BlockingQueue<T> queue) { this.queue = queue ; } + + @Override + public void send(T item) + { + try + { + if (Thread.interrupted()) throw new InterruptedException(); + // Hopefully we'll never get passed null... but just in case + if (null == item) return; + queue.put(item); + } + catch (InterruptedException e) + { + throw new CancellationException(); + } + } + + @Override + public void flush() {} + + @Override + public void close() {} +} http://git-wip-us.apache.org/repos/asf/jena/blob/1320f8db/jena-base/src/main/java/org/apache/jena/atlas/lib/SinkWrapper.java ---------------------------------------------------------------------- diff --git a/jena-base/src/main/java/org/apache/jena/atlas/lib/SinkWrapper.java b/jena-base/src/main/java/org/apache/jena/atlas/lib/SinkWrapper.java new file mode 100644 index 0000000..c6632ba --- /dev/null +++ b/jena-base/src/main/java/org/apache/jena/atlas/lib/SinkWrapper.java @@ -0,0 +1,44 @@ +/* + * 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.jena.atlas.lib; + +/** Wrap one sink in another - to pass on behaviour, the derived Sink must call super.operation + * See also: {@link SinkSplit} + */ +public class SinkWrapper<T> implements Sink<T> +{ + protected final Sink<T> sink ; + + public SinkWrapper(Sink<T> sink) + { + this.sink = sink ; + } + + @Override + public void flush() + { sink.flush(); } + + @Override + public void send(T item) + { sink.send(item) ; } + + @Override + public void close() + { sink.close(); } +} http://git-wip-us.apache.org/repos/asf/jena/blob/1320f8db/jena-base/src/main/java/org/apache/jena/atlas/lib/StrUtils.java ---------------------------------------------------------------------- diff --git a/jena-base/src/main/java/org/apache/jena/atlas/lib/StrUtils.java b/jena-base/src/main/java/org/apache/jena/atlas/lib/StrUtils.java new file mode 100644 index 0000000..9a9be76 --- /dev/null +++ b/jena-base/src/main/java/org/apache/jena/atlas/lib/StrUtils.java @@ -0,0 +1,292 @@ +/* + * 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.jena.atlas.lib; + +import java.io.UnsupportedEncodingException ; +import java.util.ArrayList ; +import java.util.List ; +import java.util.Map ; + + +public class StrUtils //extends StringUtils +{ + private StrUtils() {} + + /** strjoin with a newline as the separator */ + public static String strjoinNL(String... args) + { + return join("\n", args) ; + } + + /** strjoin with a newline as the separator */ + public static String strjoinNL(List<String> args) + { + return join("\n", args) ; + } + + /** Concatentate strings, using a separator */ + public static String strjoin(String sep, String... args) + { + return join(sep, args) ; + } + + /** Concatentate string, using a separator */ + public static String strjoin(String sep, List<String> args) + { + return join(sep, args) ; + } + + private static String join(String sep, List<String> a) + { + return join(sep, a.toArray(new String[0])) ; + } + + private static String join(String sep, String...a) + { + if ( a.length == 0 ) + return "" ; + + if ( a.length == 1) + return a[0] ; + + StringBuilder sbuff = new StringBuilder() ; + sbuff.append(a[0]) ; + + for ( int i = 1 ; i < a.length ; i++ ) + { + if ( sep != null ) + sbuff.append(sep) ; + sbuff.append(a[i]) ; + } + return sbuff.toString() ; + } + + public static final int CMP_GREATER = +1 ; + public static final int CMP_EQUAL = 0 ; + public static final int CMP_LESS = -1 ; + + public static final int CMP_UNEQUAL = -9 ; + public static final int CMP_INDETERMINATE = 2 ; + + public static int strCompare(String s1, String s2) + { + // Value is the difference of the first differing chars + int x = s1.compareTo(s2) ; + if ( x < 0 ) return CMP_LESS ; + if ( x > 0 ) return CMP_GREATER ; + if ( x == 0 ) return CMP_EQUAL ; + throw new InternalErrorException("String comparison failure") ; + } + + public static int strCompareIgnoreCase(String s1, String s2) + { + // Value is the difference of the first differing chars + int x = s1.compareToIgnoreCase(s2) ; + if ( x < 0 ) return CMP_LESS ; + if ( x > 0 ) return CMP_GREATER ; + if ( x == 0 ) return CMP_EQUAL ; + throw new InternalErrorException("String comparison failure") ; + } + + public static byte[] asUTF8bytes(String s) + { + try { return s.getBytes("UTF-8") ; } + catch (UnsupportedEncodingException ex) + { throw new InternalErrorException("UTF-8 not supported!") ; } + } + + public static String fromUTF8bytes(byte[] bytes) + { + try { return new String(bytes, "UTF-8") ; } + catch (UnsupportedEncodingException ex) + { throw new InternalErrorException("UTF-8 not supported!") ; } + } + + public static String str(Object x) + { + if ( x == null ) return "<null>" ; + return x.toString() ; + } + + /** Split but also trim whiespace. */ + public static String[] split(String s, String splitStr) + { + String[] x = s.split(splitStr) ; + for ( int i = 0 ; i < x.length ; i++ ) + { + x[i] = x[i].trim() ; + } + return x ; + } + + /** Does one string contain another string? + * @param str1 + * @param str2 + * @return true if str1 contains str2 + */ + public final static boolean contains(String str1, String str2) + { + return str1.contains(str2) ; + } + + public final static String replace(String string, String target, String replacement) + { + return string.replace(target, replacement) ; + } + + public static String substitute(String str, Map<String, String>subs) + { + for ( Map.Entry<String, String> e : subs.entrySet() ) + { + String param = e.getKey() ; + if ( str.contains(param) ) + str = str.replace(param, e.getValue()) ; + } + return str ; + } + + public static String strform(Map<String, String>subs, String... args) + { + return substitute(strjoinNL(args),subs) ; + } + + public static String chop(String x) + { + if ( x.length() == 0 ) + return x ; + return x.substring(0, x.length()-1) ; + } + + public static String noNewlineEnding(String x) + { + while ( x.endsWith("\n") || x.endsWith("\r") ) + x = StrUtils.chop(x) ; + return x ; + } + + public static List<Character> toCharList(String str) + { + List<Character> characters = new ArrayList<>(str.length()) ; + for ( Character ch : str.toCharArray() ) + characters.add(ch) ; + return characters ; + } + + // ==== Encoding and decoding strings based on a marker character (e.g. %) + // and then the hexadecimal representation of the character. + // Only characters 0-255 can be encoded. + + /** Encode a string using hex values e.g. %20 + * + * @param str String to encode + * @param marker Marker character + * @param escapees Characters to encode (must include the marker) + * @return Encoded string (returns input object if no change) + */ + public static String encodeHex(String str, char marker, char[] escapees) + { + // We make a first pass to see if there is anything to do. + // This is assuming + // (1) the string is shortish (e.g. fits in L1) + // (2) necessary escaping is not common + + int N = str.length(); + int idx = 0 ; + // Scan stage. + for ( ; idx < N ; idx++ ) + { + char ch = str.charAt(idx) ; + if ( Chars.charInArray(ch, escapees) ) + break ; + } + if ( idx == N ) + return str ; + + // At least one char to convert + StringBuilder buff = new StringBuilder() ; + buff.append(str, 0, idx) ; // Insert first part. + for ( ; idx < N ; idx++ ) + { + char ch = str.charAt(idx) ; + if ( Chars.charInArray(ch, escapees) ) + { + Chars.encodeAsHex(buff, marker, ch) ; + continue ; + } + buff.append(ch) ; + } + return buff.toString(); + } + + /** Decode a string using marked hex values e.g. %20 + * + * @param str String to decode + * @param marker The marker charcater + * @return Decoded string (returns input object on no change) + */ + public static String decodeHex(String str, char marker) + { + int idx = str.indexOf(marker) ; + if ( idx == -1 ) + return str ; + StringBuilder buff = new StringBuilder() ; + + buff.append(str, 0, idx) ; + int N = str.length() ; + + for ( ; idx < N ; idx++ ) + { + char ch = str.charAt(idx) ; + // First time through this is true, always. + if ( ch != marker ) + buff.append(ch) ; + else + { + char hi = str.charAt(idx+1) ; + char lo = str.charAt(idx+2) ; // exceptions. + char ch2 = (char)(hexDecode(hi)<<4 | hexDecode(lo)) ; + buff.append(ch2) ; + idx += 2 ; + } + } + return buff.toString() ; + } + + // Encoding is table-driven but for decode, we use code. + static private int hexDecode(char ch) { + if (ch >= '0' && ch <= '9' ) + return ch - '0' ; + if ( ch >= 'A' && ch <= 'F' ) + return ch - 'A' + 10 ; + if ( ch >= 'a' && ch <= 'f' ) + return ch - 'a' + 10 ; + return -1 ; + } + + public static String escapeString(String x) + { + return EscapeStr.stringEsc(x) ; + } + + public static String unescapeString(String x) + { + return EscapeStr.unescapeStr(x) ; + } + +} http://git-wip-us.apache.org/repos/asf/jena/blob/1320f8db/jena-base/src/main/java/org/apache/jena/atlas/lib/Sync.java ---------------------------------------------------------------------- diff --git a/jena-base/src/main/java/org/apache/jena/atlas/lib/Sync.java b/jena-base/src/main/java/org/apache/jena/atlas/lib/Sync.java new file mode 100644 index 0000000..c8e549b --- /dev/null +++ b/jena-base/src/main/java/org/apache/jena/atlas/lib/Sync.java @@ -0,0 +1,24 @@ +/* + * 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.jena.atlas.lib; + +public interface Sync +{ + public void sync() ; +} http://git-wip-us.apache.org/repos/asf/jena/blob/1320f8db/jena-base/src/main/java/org/apache/jena/atlas/lib/SystemUtils.java ---------------------------------------------------------------------- diff --git a/jena-base/src/main/java/org/apache/jena/atlas/lib/SystemUtils.java b/jena-base/src/main/java/org/apache/jena/atlas/lib/SystemUtils.java new file mode 100644 index 0000000..fa208f8 --- /dev/null +++ b/jena-base/src/main/java/org/apache/jena/atlas/lib/SystemUtils.java @@ -0,0 +1,57 @@ +/* + * 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.jena.atlas.lib; + +import org.apache.jena.atlas.AtlasException ; +import org.slf4j.Logger ; +import org.slf4j.LoggerFactory ; + +public class SystemUtils +{ + private static Logger log = LoggerFactory.getLogger(SystemUtils.class.getName()); + // Unfortunately, this tends to cause confusing logging. + private static boolean logging = false ; + + static public ClassLoader chooseClassLoader() + { + ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); + + if ( logging && classLoader != null ) + log.trace("Using thread classloader") ; + +// if (classLoader == null) +// { +// classLoader = this.getClass().getClassLoader(); +// if ( classLoader != null ) +// logger.trace("Using 'this' classloader") ; +// } + + if ( classLoader == null ) + { + classLoader = ClassLoader.getSystemClassLoader() ; + if ( logging && classLoader != null ) + log.trace("Using system classloader") ; + } + + if ( classLoader == null ) + throw new AtlasException("Failed to find a classloader") ; + return classLoader ; + } + +} http://git-wip-us.apache.org/repos/asf/jena/blob/1320f8db/jena-base/src/main/java/org/apache/jena/atlas/lib/Timer.java ---------------------------------------------------------------------- diff --git a/jena-base/src/main/java/org/apache/jena/atlas/lib/Timer.java b/jena-base/src/main/java/org/apache/jena/atlas/lib/Timer.java new file mode 100644 index 0000000..304e086 --- /dev/null +++ b/jena-base/src/main/java/org/apache/jena/atlas/lib/Timer.java @@ -0,0 +1,72 @@ +/* + * 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.jena.atlas.lib ; + +import org.apache.jena.atlas.AtlasException ; + +/** A Timer of operations */ +public class Timer { + + protected long timeFinish = -1 ; + protected boolean inTimer = false ; + protected long timeStart = 0 ; + + public Timer() {} + + public void startTimer() { + if ( inTimer ) + throw new AtlasException("Already in timer") ; + + timeStart = System.currentTimeMillis() ; + timeFinish = -1 ; + inTimer = true ; + } + + /** Return time in millisecods */ + public long endTimer() { + if ( !inTimer ) + throw new AtlasException("Not in timer") ; + timeFinish = System.currentTimeMillis() ; + inTimer = false ; + return getTimeInterval() ; + } + + public long readTimer() { + if ( !inTimer ) + throw new AtlasException("Not in timer") ; + return System.currentTimeMillis() - timeStart ; + } + + public long getTimeInterval() { + if ( inTimer ) + throw new AtlasException("Still timing") ; + if ( timeFinish == -1 ) + throw new AtlasException("No valid interval") ; + + return timeFinish - timeStart ; + } + + static public String timeStr(long timeInterval) { + return String.format("%.3f", timeInterval / 1000.0) ; + } + + protected String timeStr(long timePoint, long startTimePoint) { + return timeStr(timePoint - startTimePoint) ; + } +} http://git-wip-us.apache.org/repos/asf/jena/blob/1320f8db/jena-base/src/main/java/org/apache/jena/atlas/lib/Trie.java ---------------------------------------------------------------------- diff --git a/jena-base/src/main/java/org/apache/jena/atlas/lib/Trie.java b/jena-base/src/main/java/org/apache/jena/atlas/lib/Trie.java new file mode 100644 index 0000000..0d823bc --- /dev/null +++ b/jena-base/src/main/java/org/apache/jena/atlas/lib/Trie.java @@ -0,0 +1,407 @@ +/* + * 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.jena.atlas.lib; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * An implementation of a classic Trie, this is a mapping from strings to some + * value type optimized for fast prefix search and match. If you do not need + * prefix search then you should typically use a standard {@link Map} instead. + * <p> + * The empty or null string may be used as a special key to refer to the root + * node of the trie. + * </p> + * <p> + * A Trie cannot store null values since null is used as an internal marker to + * indicate that there is no value associated with a key. This is necessary + * because the nature of the data structure means that adding a key potentially + * adds multiple keys many of which will not be associated with a value. + * </p> + * + * @param <T> + * Type of the value stored. + */ +public final class Trie<T> { + + private TrieNode<T> root = new TrieNode<>(null); + + /** + * Adds a value to the trie overwriting any existing value + * <p> + * Note that a null value is treated as if the key does not actually exist + * in the tree so trying to add a null is a no-op. If you want to remove a + * key use the {@link #remove(String)} method instead. + * </p> + * + * @param key + * Key + * @param value + * Value + */ + public void add(String key, T value) { + if (value == null) + return; + TrieNode<T> n = this.moveToNode(key); + n.setValue(value); + } + + /** + * Move to a node creating new nodes if necessary + * + * @param key + * Key + * @return Node + */ + private TrieNode<T> moveToNode(String key) { + TrieNode<T> current = this.root; + if (key == null) + return current; + for (int i = 0; i < key.length(); i++) { + current = current.moveToChild(key.charAt(i)); + } + return current; + } + + /** + * Try to find a node in the trie + * + * @param key + * Key + * @return Node or null if not found + */ + private TrieNode<T> find(String key) { + TrieNode<T> current = this.root; + if (key == null) + return current; + for (int i = 0; i < key.length(); i++) { + current = current.getChild(key.charAt(i)); + if (current == null) + break; + } + return current; + } + + /** + * Removes a value from the trie + * <p> + * This doesn't actually remove the key per-se rather sets the value + * associated with the key to null. + * </p> + * + * @param key + * Key + */ + public void remove(String key) { + TrieNode<T> n = this.find(key); + if (n != null) { + n.setValue(null); + } + } + + /** + * Gets whether a key exists in the trie and has a non-null value mapped to + * it + * + * @param key + * Key + * @return True if the key exists and has a non-null value mapped to it + */ + public boolean contains(String key) { + return this.contains(key, true); + } + + /** + * Gets whether a key exists in the trie and meets the given value criteria + * + * @param key + * Key + * @param requireValue + * If true a key must have a non-null value associated with it to + * be considered to be contained in the tree, if false then the + * key must merely map to a node in the trie + * @return True if the key exists and the value criteria is met, false + * otherwise + */ + public boolean contains(String key, boolean requireValue) { + TrieNode<T> n = this.find(key); + if (n == null) + return false; + if (requireValue) { + return n.hasValue(); + } else { + return true; + } + } + + /** + * Gets whether a key value pair are present in the trie + * + * @param key + * Key + * @param value + * Value + * @return True if the key value pair exists in the trie, false otherwise + */ + public boolean contains(String key, T value) { + TrieNode<T> n = this.find(key); + if (n == null) + return false; + if (value == null && !n.hasValue()) + return true; + return value.equals(n.getValue()); + } + + /** + * Gets the value associated with a key + * + * @param key + * Key + * @return Value + */ + public T get(String key) { + TrieNode<T> n = this.find(key); + if (n == null) + return null; + return n.getValue(); + } + + /** + * Performs a prefix search and returns all values mapped under the given + * prefix. The entirety of the prefix must be matches, if you only want part + * of the prefix to be matched use the {@link #partialSearch(String)} method + * instead. + * + * @param prefix + * Prefix + * @return List of values associated with the given key + */ + public List<T> prefixSearch(String prefix) { + TrieNode<T> n = this.find(prefix); + if (n == null) + return new ArrayList<>(); + return Collections.unmodifiableList(n.getValues()); + } + + /** + * Performs a search and returns any value associated with any partial or + * whole prefix of the key + * + * @param key + * Key + * @return List of values associated with any partial prefix of the key + */ + public List<T> partialSearch(String key) { + List<T> values = new ArrayList<>(); + TrieNode<T> current = this.root; + if (key == null) { + if (current.hasValue()) + values.add(current.getValue()); + } else { + for (int i = 0; i < key.length(); i++) { + if (current.hasValue()) + values.add(current.getValue()); + current = current.getChild(key.charAt(i)); + if (current == null) + return Collections.unmodifiableList(values); + } + + // If we reach here current is the complete key match + // so make sure to include it in the values list + if (current.hasValue()) { + values.add(current.getValue()); + } + + } + return Collections.unmodifiableList(values); + } + + /** + * Finds the shortest match for a given key i.e. returns the value + * associated with the shortest prefix of the key that has a value + * + * @param key + * Key + * @return Shortest Match or null if no possible matches + */ + public T shortestMatch(String key) { + TrieNode<T> current = this.root; + if (key == null) + return current.getValue(); + for (int i = 0; i < key.length(); i++) { + if (current.hasValue()) + break; + current = current.getChild(key.charAt(i)); + if (current == null) + return null; + } + return current.getValue(); + } + + /** + * Finds the longest match for a given key i.e. returns the value associated + * with the longest prefix of the key that has a value + * + * @param key + * Key + * @return Longest Match or null if no possible matches + */ + public T longestMatch(String key) { + T value = null; + TrieNode<T> current = this.root; + if (key == null) { + return current.getValue(); + } else { + for (int i = 0; i < key.length(); i++) { + if (current.hasValue()) + value = current.getValue(); + current = current.getChild(key.charAt(i)); + if (current == null) + return value; + } + // If we reach here current is the complete key match + // so return its value if it has one + if (current.hasValue()) { + return current.getValue(); + } + } + return value; + } + + /** + * Represents a node in the Trie + * <p> + * The implementation is designed to be sparse such that we delay creation + * of things at both leafs and interior nodes until they are actually needed + * </p> + * + */ + private static class TrieNode<T> { + private Map<Character, TrieNode<T>> children = null; + private Character singletonChildChar = null; + private TrieNode<T> singletonChild = null; + private T value; + + /** + * Creates a Trie Node + * + * @param value + * Value + */ + public TrieNode(T value) { + this.value = value; + } + + /** + * Gets the value + * + * @return Value + */ + public T getValue() { + return this.value; + } + + /** + * Sets the value + * + * @param value + * Value + */ + public void setValue(T value) { + this.value = value; + } + + /** + * Returns whether a non-null value is associated with this node + * + * @return True if there is a non-null value, false otherwise + */ + public boolean hasValue() { + return this.value != null; + } + + /** + * Gets the child (if it exists) + * + * @param c + * Character to move to + * @return Child + */ + public TrieNode<T> getChild(Character c) { + if (this.children != null) { + return this.children.get(c); + } else if (c.equals(this.singletonChildChar)) { + return this.singletonChild; + } else { + return null; + } + } + + /** + * Moves to a child (creating a new node if necessary) + * + * @param c + * Character to move to + * @return Child + */ + public TrieNode<T> moveToChild(Character c) { + TrieNode<T> n = this.getChild(c); + if (n == null) { + n = new TrieNode<>(null); + if (this.children != null) { + // Add to existing map + this.children.put(c, n); + } else if (this.singletonChildChar != null) { + // Need to lazily create map + this.children = new HashMap<>(); + this.children.put(this.singletonChildChar, this.singletonChild); + this.children.put(c, n); + } else { + // Singleton child + this.singletonChildChar = c; + this.singletonChild = n; + } + } + return n; + } + + /** + * Gets all values from a given node and its descendants + * + * @return Values + */ + public List<T> getValues() { + List<T> values = new ArrayList<>(); + if (this.hasValue()) { + values.add(this.value); + } + if (this.children != null) { + for (TrieNode<T> child : this.children.values()) { + values.addAll(child.getValues()); + } + } else if (this.singletonChild != null) { + values.addAll(this.singletonChild.getValues()); + } + return values; + } + } +} http://git-wip-us.apache.org/repos/asf/jena/blob/1320f8db/jena-base/src/main/java/org/apache/jena/atlas/lib/Tuple.java ---------------------------------------------------------------------- diff --git a/jena-base/src/main/java/org/apache/jena/atlas/lib/Tuple.java b/jena-base/src/main/java/org/apache/jena/atlas/lib/Tuple.java new file mode 100644 index 0000000..ae944a7 --- /dev/null +++ b/jena-base/src/main/java/org/apache/jena/atlas/lib/Tuple.java @@ -0,0 +1,153 @@ +/* + * 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.jena.atlas.lib ; + +import java.util.Arrays ; +import java.util.Iterator ; +import java.util.List ; + +import org.apache.jena.atlas.iterator.Iter ; +import org.apache.jena.atlas.iterator.IteratorArray ; +import org.apache.jena.atlas.iterator.Transform ; + +/** Tuple class - tuples are immutable and must be created initialized */ +public class Tuple<T> implements Iterable<T> { + // Interface this? + // Classes: TupleImpl, TupleSlice + public static <X> Tuple<X> createTuple(@SuppressWarnings("unchecked") X... elements) { + X[] els = elements ; // ArrayUtils.copy(elements) ; + return create(els) ; + } + + /** + * Create a tuple from an array of elements. The array is not copied and + * should not be modified after this call. + * <p> + * There is also a {@link TupleBuilder} which does create an idendent + * copy, in case that style is preferrable for creating tuples. + */ + public static <X> Tuple<X> create(X[] elements) { + return new Tuple<>(elements) ; + } + + // TupleLib?? + public static <T> Iterator<T> project(final int slot, Iterator<Tuple<T>> iter) { + Transform<Tuple<T>, T> projection = new Transform<Tuple<T>, T>() { + @Override + public T convert(Tuple<T> tuple) { + return tuple.get(slot) ; + } + } ; + return Iter.map(iter, projection) ; + } + + public static <T> Iterator<Tuple<T>> prefix(final int prefixLength, Iterator<Tuple<T>> iter) { + Transform<Tuple<T>, Tuple<T>> sub = new Transform<Tuple<T>, Tuple<T>>() { + @Override + public Tuple<T> convert(Tuple<T> tuple) { + T[] x = ArrayUtils.copy(tuple.tuple, 0, prefixLength) ; + return Tuple.create(x) ; + } + } ; + return Iter.map(iter, sub) ; + } + + protected final T[] tuple ; + + protected Tuple(@SuppressWarnings("unchecked") T... tuple) { + this.tuple = tuple ; + } + + public T get(int idx) { + return tuple[idx] ; + } + + public int countNotNull() { + int x = 0 ; + for ( T item : tuple ) + if ( item != null ) + x++ ; + return x ; + } + + public List<T> asList() { + return Arrays.asList(tuple) ; + } + + public T[] tuple() { + return tuple ; + } + + public T[] tupleCopy() { + return ArrayUtils.copy(tuple) ; + } + + @Override + public Iterator<T> iterator() { + return IteratorArray.create(tuple) ; + } + + /** Return a tuple with the column mapping applied */ + public Tuple<T> map(ColumnMap colMap) { + return colMap.map(this) ; + } + + /** Return a tuple with the column mapping reversed */ + public Tuple<T> unmap(ColumnMap colMap) { + return colMap.unmap(this) ; + } + + public int size() { + return tuple.length ; + } + + @Override + public int hashCode() { + int x = 99 ; + for ( T n : tuple ) { + if ( n != null ) + x = x << 1 ^ n.hashCode() ; + } + return x ; + } + + /** Equality of tuples is based on equality of the elements in the tuple */ + @Override + public boolean equals(Object other) { + if ( this == other ) + return true ; + if ( !(other instanceof Tuple<? >) ) + return false ; + Tuple<? > x = (Tuple<? >)other ; + if ( x.size() != this.size() ) + return false ; + for ( int i = 0 ; i < tuple.length ; i++ ) { + Object obj1 = tuple[i] ; + Object obj2 = x.tuple[i] ; + if ( !Lib.equal(obj1, obj2) ) + return false ; + } + return true ; + } + + @Override + public String toString() { + return "[" + Iter.asString(iterator(), ", ") + "]" ; + } +} http://git-wip-us.apache.org/repos/asf/jena/blob/1320f8db/jena-base/src/main/java/org/apache/jena/atlas/lib/TupleBuilder.java ---------------------------------------------------------------------- diff --git a/jena-base/src/main/java/org/apache/jena/atlas/lib/TupleBuilder.java b/jena-base/src/main/java/org/apache/jena/atlas/lib/TupleBuilder.java new file mode 100644 index 0000000..278334d --- /dev/null +++ b/jena-base/src/main/java/org/apache/jena/atlas/lib/TupleBuilder.java @@ -0,0 +1,50 @@ +/* + * 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.jena.atlas.lib; + + +import java.util.ArrayList ; +import java.util.List ; + +/** Tuple builder class - tuples are immutable, this is how to create them in the builder style */ +public class TupleBuilder<T> +{ + private List<T> x = new ArrayList<>() ; + + public TupleBuilder() { } + + public TupleBuilder<T> add(T element) { + x.add(element) ; + return this ; + } + + public TupleBuilder<T> reset() { + x.clear() ; + return this ; + } + + public Tuple<T> build() { + @SuppressWarnings("unchecked") + T[] elts = (T[])new Object[x.size()] ; + // Copy contents, should not create a new array because elts + // is created with the right size so elts == elts2 + T[] elts2 = x.toArray(elts) ; + return new Tuple<>(elts2) ; + } +} http://git-wip-us.apache.org/repos/asf/jena/blob/1320f8db/jena-base/src/main/java/org/apache/jena/atlas/lib/XMLLib.java ---------------------------------------------------------------------- diff --git a/jena-base/src/main/java/org/apache/jena/atlas/lib/XMLLib.java b/jena-base/src/main/java/org/apache/jena/atlas/lib/XMLLib.java new file mode 100644 index 0000000..e8640df --- /dev/null +++ b/jena-base/src/main/java/org/apache/jena/atlas/lib/XMLLib.java @@ -0,0 +1,62 @@ +/* + * 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.jena.atlas.lib; + +/** Operations in someway related to XML */ +public class XMLLib +{ + /** Trim the XML whitespace characters strictly needed for whitespace facet collapse. + * This <b>not</b> full whitespace facet collapse, which also requires processing of + * internal spaces. Because none of the datatypes that have whitespace facet + * collapse and have values we extract can legally contain internal whitespace, + * we just need to trim the string. + * + * Java String.trim removes any characters less than 0x20. + */ + static String WScollapse(String string) + { + int len = string.length(); + if ( len == 0 ) + return string ; + + if ( (string.charAt(0) > 0x20) && (string.charAt(len-1) > 0x20) ) + return string ; + + int idx1 = 0 ; + for ( ; idx1 < len ; idx1++ ) + { + char ch = string.charAt(idx1) ; + if ( ! testForWS(ch) ) + break ; + } + int idx2 = len-1 ; + for ( ; idx2 > idx1 ; idx2-- ) + { + char ch = string.charAt(idx2) ; + if ( ! testForWS(ch) ) + break ; + } + return string.substring(idx1, idx2+1) ; + } + + private static boolean testForWS(char ch) + { + return ch == ' ' || ch == '\n' || ch == '\r' || ch == '\t' ; + } +} http://git-wip-us.apache.org/repos/asf/jena/blob/1320f8db/jena-base/src/main/java/org/apache/jena/atlas/lib/cache/Cache0.java ---------------------------------------------------------------------- diff --git a/jena-base/src/main/java/org/apache/jena/atlas/lib/cache/Cache0.java b/jena-base/src/main/java/org/apache/jena/atlas/lib/cache/Cache0.java new file mode 100644 index 0000000..00befa0 --- /dev/null +++ b/jena-base/src/main/java/org/apache/jena/atlas/lib/cache/Cache0.java @@ -0,0 +1,72 @@ +/* + * 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.jena.atlas.lib.cache ; + +import java.util.Iterator ; +import java.util.concurrent.Callable ; + +import org.apache.jena.atlas.iterator.Iter ; +import org.apache.jena.atlas.lib.ActionKeyValue ; +import org.apache.jena.atlas.lib.Cache ; + +/** A cache that keeps nothing */ +public final class Cache0<K, V> implements Cache<K, V> { + @Override + public boolean containsKey(K key) { + return false ; + } + + @Override + public V getIfPresent(K key) { + return null ; + } + + @Override + public V getOrFill(K key, Callable<V> callable) { + return null ; + } + + @Override + public void put(K key, V thing) {} + + @Override + public void remove(K key) {} + + @Override + public Iterator<K> keys() { + return Iter.nullIterator() ; + } + + @Override + public boolean isEmpty() { + return true ; + } + + @Override + public void clear() {} + + @Override + public long size() { + return 0 ; + } + + @Override + public void setDropHandler(ActionKeyValue<K, V> dropHandler) {} + +} http://git-wip-us.apache.org/repos/asf/jena/blob/1320f8db/jena-base/src/main/java/org/apache/jena/atlas/lib/cache/Cache1.java ---------------------------------------------------------------------- diff --git a/jena-base/src/main/java/org/apache/jena/atlas/lib/cache/Cache1.java b/jena-base/src/main/java/org/apache/jena/atlas/lib/cache/Cache1.java new file mode 100644 index 0000000..38ab5c6 --- /dev/null +++ b/jena-base/src/main/java/org/apache/jena/atlas/lib/cache/Cache1.java @@ -0,0 +1,127 @@ +/* + * 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.jena.atlas.lib.cache; + +import java.util.Iterator ; +import java.util.concurrent.Callable ; + +import org.apache.jena.atlas.iterator.SingletonIterator ; +import org.apache.jena.atlas.lib.ActionKeyValue ; +import org.apache.jena.atlas.lib.Cache ; +import org.apache.jena.atlas.lib.Lib ; + +/** A one-slot cache.*/ +public class Cache1<K, V> implements Cache<K,V> +{ + private ActionKeyValue<K, V> dropHandler = null ; + private K cacheKey ; + private V cacheValue ; + + public Cache1() { clear() ; } + + @Override + public boolean containsKey(K key) + { + if ( cacheKey == null ) + return false ; + return cacheKey.equals(key) ; + } + + @Override + public V getIfPresent(K key) + { + if ( cacheKey == null ) return null ; + if ( cacheKey.equals(key) ) return cacheValue ; + return null ; + } + + @Override + public V getOrFill(K key, Callable<V> callable) { + return CacheOps.getOrFillSync(this, key, callable) ; + } + + @Override + public void clear() + { + if ( cacheKey == null ) + return ; + + K k = cacheKey ; + V v = cacheValue ; + cacheKey = null ; + cacheValue = null ; + + notifyDrop(k, v) ; + } + + @Override + public boolean isEmpty() + { + return cacheKey == null ; + } + + @Override + public Iterator<K> keys() + { + return new SingletonIterator<>(cacheKey) ; + } + + @Override + public void put(K key, V thing) + { + if ( Lib.equal(cacheKey, key) && Lib.equal(cacheValue, thing) ) + // No change. + return ; + + // Change + K k = cacheKey ; + V v = cacheValue ; + // Displaces any existing cached key/value pair + cacheKey = key ; + cacheValue = thing ; + notifyDrop(k, v) ; + } + + @Override + public void remove(K key) + { + if ( cacheKey == null ) return ; + if ( cacheKey.equals(key) ) + clear() ; // Will notify + } + + @Override + public void setDropHandler(ActionKeyValue<K, V> dropHandler) + { + this.dropHandler = dropHandler ; + } + + private void notifyDrop(K key, V thing) + { + if ( dropHandler != null && key != null ) + dropHandler.apply(key, thing) ; + } + + @Override + public long size() + { + return (cacheKey == null) ? 0 : 1 ; + } + +} http://git-wip-us.apache.org/repos/asf/jena/blob/1320f8db/jena-base/src/main/java/org/apache/jena/atlas/lib/cache/CacheGuava.java ---------------------------------------------------------------------- diff --git a/jena-base/src/main/java/org/apache/jena/atlas/lib/cache/CacheGuava.java b/jena-base/src/main/java/org/apache/jena/atlas/lib/cache/CacheGuava.java new file mode 100644 index 0000000..fd5959c --- /dev/null +++ b/jena-base/src/main/java/org/apache/jena/atlas/lib/cache/CacheGuava.java @@ -0,0 +1,119 @@ +/** + * 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.jena.atlas.lib.cache; + +import java.util.Iterator ; +import java.util.concurrent.Callable ; +import java.util.concurrent.ExecutionException ; + +import org.apache.jena.atlas.lib.ActionKeyValue ; +import org.apache.jena.atlas.lib.Cache ; +import org.apache.jena.atlas.logging.Log ; + +import org.apache.jena.ext.com.google.common.cache.CacheBuilder ; +import org.apache.jena.ext.com.google.common.cache.RemovalListener ; +import org.apache.jena.ext.com.google.common.cache.RemovalNotification ; + +/** Wrapper around com.google.common.cache */ +final +public class CacheGuava<K,V> implements Cache<K, V> +{ + private ActionKeyValue<K, V> dropHandler = null ; + /*private*/ org.apache.jena.ext.com.google.common.cache.Cache<K,V> cache ; + + public CacheGuava(int size) + { + RemovalListener<K,V> drop = new RemovalListener<K, V>() { + @Override + public void onRemoval(RemovalNotification<K, V> notification) { + if ( dropHandler != null ) + dropHandler.apply(notification.getKey(), + notification.getValue()) ; + } + } ; + cache = CacheBuilder.newBuilder() + .maximumSize(size) + .removalListener(drop) + .recordStats() + .concurrencyLevel(8) + .build() ; + } + + // Change the interface to be ... + @Override + public V getOrFill(K key, Callable<V> filler) { + try { + return cache.get(key, filler) ; + } + catch (ExecutionException e) { + Log.warn(CacheGuava.class, "Execution exception filling cache", e) ; + return null ; + } + } + + @Override + public V getIfPresent(K key) { + return cache.getIfPresent(key) ; + } + + @Override + public void put(K key, V thing) { + if ( thing == null ) { + cache.invalidate(key); + return ; + } + cache.put(key, thing) ; + } + + @Override + public boolean containsKey(K key) { + return cache.getIfPresent(key) != null ; + } + + @Override + public void remove(K key) { + cache.invalidate(key) ; + } + + @Override + public Iterator<K> keys() { + return cache.asMap().keySet().iterator() ; + } + + @Override + public boolean isEmpty() { + return cache.size() == 0 ; + } + + @Override + public void clear() { + cache.invalidateAll() ; + } + + @Override + public long size() { + return cache.size() ; + } + + @Override + public void setDropHandler(ActionKeyValue<K, V> dropHandler) { + this.dropHandler = dropHandler ; + } +} + http://git-wip-us.apache.org/repos/asf/jena/blob/1320f8db/jena-base/src/main/java/org/apache/jena/atlas/lib/cache/CacheOps.java ---------------------------------------------------------------------- diff --git a/jena-base/src/main/java/org/apache/jena/atlas/lib/cache/CacheOps.java b/jena-base/src/main/java/org/apache/jena/atlas/lib/cache/CacheOps.java new file mode 100644 index 0000000..c8560bb --- /dev/null +++ b/jena-base/src/main/java/org/apache/jena/atlas/lib/cache/CacheOps.java @@ -0,0 +1,50 @@ +/** + * 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.jena.atlas.lib.cache; + +import java.util.concurrent.Callable ; + +import org.apache.jena.atlas.AtlasException ; +import org.apache.jena.atlas.lib.Cache ; + +/** Support operations for Cache functions */ +class CacheOps { + + /** Implementation of getOrFill based on Cache.get and Cache.put */ + public static <K,V> V getOrFill(Cache<K,V> cache, K key, Callable<V> callable) { + V value = cache.getIfPresent(key) ; + if ( value == null ) { + try { value = callable.call() ; } + catch (Exception e) { + throw new AtlasException("Exception on cache fill", e) ; + } + if ( value != null ) + cache.put(key, value) ; + } + return value ; + } + + /** Thread safe implementation of getOrFill based on Cache.get and Cache.put */ + public static <K,V> V getOrFillSync(Cache<K,V> cache, K key, Callable<V> callable) { + synchronized(cache) { + return getOrFill(cache, key, callable) ; + } + } +} + http://git-wip-us.apache.org/repos/asf/jena/blob/1320f8db/jena-base/src/main/java/org/apache/jena/atlas/lib/cache/CacheSetImpl.java ---------------------------------------------------------------------- diff --git a/jena-base/src/main/java/org/apache/jena/atlas/lib/cache/CacheSetImpl.java b/jena-base/src/main/java/org/apache/jena/atlas/lib/cache/CacheSetImpl.java new file mode 100644 index 0000000..b3bf048 --- /dev/null +++ b/jena-base/src/main/java/org/apache/jena/atlas/lib/cache/CacheSetImpl.java @@ -0,0 +1,93 @@ +/* + * 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.jena.atlas.lib.cache ; + +import java.util.Iterator ; + +import org.apache.jena.atlas.iterator.Action ; +import org.apache.jena.atlas.lib.ActionKeyValue ; +import org.apache.jena.atlas.lib.Cache ; +import org.apache.jena.atlas.lib.CacheSet ; + +/** Cache set */ +public class CacheSetImpl<T> implements CacheSet<T> { + // LinkHashSet does not have LRU support. + static Object theOnlyValue = new Object() ; + Cache<T, Object> cacheMap = null ; + + public CacheSetImpl(Cache<T, Object> cache) { + cacheMap = cache ; + } + + /** Callback for entries when dropped from the cache */ + @Override + public void setDropHandler(Action<T> dropHandler) { + cacheMap.setDropHandler(new Wrapper<T>(dropHandler)) ; + } + + // From map action to set action. + static class Wrapper<T> implements ActionKeyValue<T, Object> { + Action<T> dropHandler ; + + public Wrapper(Action<T> dropHandler) { + this.dropHandler = dropHandler ; + } + + @Override + public void apply(T key, Object value) { + dropHandler.apply(key) ; + } + + } + + @Override + public void add(T e) { + cacheMap.put(e, theOnlyValue) ; + } + + @Override + public void clear() { + cacheMap.clear() ; + } + + @Override + public boolean contains(T obj) { + return cacheMap.containsKey(obj) ; + } + + @Override + public boolean isEmpty() { + return cacheMap.isEmpty() ; + } + + public Iterator<T> iterator() { + return cacheMap.keys() ; + } + + @Override + public void remove(T obj) { + cacheMap.remove(obj) ; + } + + @Override + public long size() { + return cacheMap.size() ; + } + +} http://git-wip-us.apache.org/repos/asf/jena/blob/1320f8db/jena-base/src/main/java/org/apache/jena/atlas/lib/cache/CacheSetSync.java ---------------------------------------------------------------------- diff --git a/jena-base/src/main/java/org/apache/jena/atlas/lib/cache/CacheSetSync.java b/jena-base/src/main/java/org/apache/jena/atlas/lib/cache/CacheSetSync.java new file mode 100644 index 0000000..fc3a3bd --- /dev/null +++ b/jena-base/src/main/java/org/apache/jena/atlas/lib/cache/CacheSetSync.java @@ -0,0 +1,65 @@ +/* + * 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.jena.atlas.lib.cache ; + +import org.apache.jena.atlas.iterator.Action ; +import org.apache.jena.atlas.lib.CacheSet ; + +public class CacheSetSync<T> implements CacheSet<T> { + private CacheSet<T> cache ; + + public CacheSetSync(CacheSet<T> cache) { + this.cache = cache ; + } + + @Override + synchronized public void add(T e) { + cache.add(e) ; + } + + @Override + synchronized public void clear() { + cache.clear() ; + } + + @Override + synchronized public boolean contains(T obj) { + return cache.contains(obj) ; + } + + @Override + synchronized public boolean isEmpty() { + return cache.isEmpty() ; + } + + @Override + synchronized public void remove(T obj) { + cache.remove(obj) ; + } + + @Override + synchronized public long size() { + return cache.size() ; + } + + @Override + synchronized public void setDropHandler(Action<T> dropHandler) { + cache.setDropHandler(dropHandler) ; + } +} http://git-wip-us.apache.org/repos/asf/jena/blob/1320f8db/jena-base/src/main/java/org/apache/jena/atlas/lib/cache/CacheSetWrapper.java ---------------------------------------------------------------------- diff --git a/jena-base/src/main/java/org/apache/jena/atlas/lib/cache/CacheSetWrapper.java b/jena-base/src/main/java/org/apache/jena/atlas/lib/cache/CacheSetWrapper.java new file mode 100644 index 0000000..c11ffb0 --- /dev/null +++ b/jena-base/src/main/java/org/apache/jena/atlas/lib/cache/CacheSetWrapper.java @@ -0,0 +1,65 @@ +/* + * 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.jena.atlas.lib.cache ; + +import org.apache.jena.atlas.iterator.Action ; +import org.apache.jena.atlas.lib.CacheSet ; + +public class CacheSetWrapper<T> implements CacheSet<T> { + private CacheSet<T> cache ; + + public CacheSetWrapper(CacheSet<T> cache) { + this.cache = cache ; + } + + @Override + public void add(T e) { + cache.add(e) ; + } + + @Override + public void clear() { + cache.clear() ; + } + + @Override + public boolean contains(T obj) { + return cache.contains(obj) ; + } + + @Override + public boolean isEmpty() { + return cache.isEmpty() ; + } + + @Override + public void remove(T obj) { + cache.remove(obj) ; + } + + @Override + public long size() { + return cache.size() ; + } + + @Override + public void setDropHandler(Action<T> dropHandler) { + cache.setDropHandler(dropHandler) ; + } +} http://git-wip-us.apache.org/repos/asf/jena/blob/1320f8db/jena-base/src/main/java/org/apache/jena/atlas/lib/cache/CacheSimple.java ---------------------------------------------------------------------- diff --git a/jena-base/src/main/java/org/apache/jena/atlas/lib/cache/CacheSimple.java b/jena-base/src/main/java/org/apache/jena/atlas/lib/cache/CacheSimple.java new file mode 100644 index 0000000..a33d8e2 --- /dev/null +++ b/jena-base/src/main/java/org/apache/jena/atlas/lib/cache/CacheSimple.java @@ -0,0 +1,161 @@ +/* + * 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.jena.atlas.lib.cache; + +import java.util.Arrays ; +import java.util.Iterator ; +import java.util.concurrent.Callable ; + +import org.apache.jena.atlas.iterator.Iter ; +import org.apache.jena.atlas.iterator.IteratorArray ; +import org.apache.jena.atlas.lib.ActionKeyValue ; +import org.apache.jena.atlas.lib.Cache ; + + +/** + * A simple fixed size cache that uses the hash code to address a slot. + * Clash policy is to overwrite. + * No object creation during lookup or insert. + */ + +public class CacheSimple<K,V> implements Cache<K,V> +{ + private final V[] values ; + private final K[] keys ; + private final int size ; + private int currentSize = 0 ; + private ActionKeyValue<K,V> dropHandler = null ; + + public CacheSimple(int size) + { + @SuppressWarnings("unchecked") + V[] x = (V[])new Object[size] ; + values = x ; + + @SuppressWarnings("unchecked") + K[] z = (K[])new Object[size] ; + keys = z ; + + this.size = size ; + } + + + @Override + public void clear() + { + Arrays.fill(values, null) ; + Arrays.fill(keys, null) ; + // drop handler + currentSize = 0 ; + } + + @Override + public boolean containsKey(K key) + { + return getIfPresent(key) != null ; + } + + // Return key index : -(index+1) if the key does not match + private final int index(K key) + { + int x = (key.hashCode()&0x7fffffff) % size ; + if ( keys[x] != null && keys[x].equals(key) ) + return x ; + return -x-1 ; + } + + private final int decode(int x) + { + if ( x >= 0 ) return x ; + return -x-1 ; + } + + @Override + public V getIfPresent(K key) + { + int x = index(key) ; + if ( x < 0 ) + return null ; + return values[x] ; + } + + @Override + public V getOrFill(K key, Callable<V> callable) { + return CacheOps.getOrFill(this, key, callable) ; + } + + @Override + public void put(K key, V thing) + { + int x = index(key) ; + V old = null ; + if ( x < 0 ) + // New. + x = decode(x) ; + else + { + // Drop the old K->V + old = values[x] ; + if ( dropHandler != null ) + dropHandler.apply(keys[x], old) ; + currentSize-- ; + } + + values[x] = thing ; + if ( thing == null ) + //put(,null) is a remove. + keys[x] = null ; + else { + keys[x] = key ; + currentSize++ ; + } + } + + @Override + public void remove(K key) + { + put(key, null) ; + } + + @Override + public long size() + { + return currentSize ; + } + + @Override + public Iterator<K> keys() + { + Iterator<K> iter = IteratorArray.create(keys) ; + return Iter.removeNulls(iter) ; + } + + @Override + public boolean isEmpty() + { + return currentSize == 0 ; + } + + /** Callback for entries when dropped from the cache */ + @Override + public void setDropHandler(ActionKeyValue<K,V> dropHandler) + { + this.dropHandler = dropHandler ; + } +} http://git-wip-us.apache.org/repos/asf/jena/blob/1320f8db/jena-base/src/main/java/org/apache/jena/atlas/lib/cache/CacheWrapper.java ---------------------------------------------------------------------- diff --git a/jena-base/src/main/java/org/apache/jena/atlas/lib/cache/CacheWrapper.java b/jena-base/src/main/java/org/apache/jena/atlas/lib/cache/CacheWrapper.java new file mode 100644 index 0000000..e655749 --- /dev/null +++ b/jena-base/src/main/java/org/apache/jena/atlas/lib/cache/CacheWrapper.java @@ -0,0 +1,65 @@ +/* + * 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.jena.atlas.lib.cache; +import java.util.Iterator ; +import java.util.concurrent.Callable ; + +import org.apache.jena.atlas.lib.ActionKeyValue ; +import org.apache.jena.atlas.lib.Cache ; + + + +public class CacheWrapper<Key,T> implements Cache<Key,T> +{ + protected Cache<Key,T> cache ; + + public CacheWrapper(Cache<Key,T> cache) { this.cache = cache ; } + + @Override + public void clear() { cache.clear(); } + + @Override + public boolean containsKey(Key key) { return cache.containsKey(key) ; } + + @Override + public T getIfPresent(Key key) { return cache.getIfPresent(key) ; } + + @Override + public T getOrFill(Key key, Callable<T> callable) { return cache.getOrFill(key, callable) ; } + + @Override + public boolean isEmpty() { return cache.isEmpty() ; } + + @Override + public Iterator<Key> keys() { return cache.keys(); } + + @Override + public void put(Key key, T thing) { cache.put(key, thing) ; } + + @Override + public void remove(Key key) { cache.remove(key) ; } + + @Override + public void setDropHandler(ActionKeyValue<Key, T> dropHandler) + { cache.setDropHandler(dropHandler) ; } + + @Override + public long size() { return cache.size() ; } + +} http://git-wip-us.apache.org/repos/asf/jena/blob/1320f8db/jena-base/src/main/java/org/apache/jena/atlas/lib/cache/Getter.java ---------------------------------------------------------------------- diff --git a/jena-base/src/main/java/org/apache/jena/atlas/lib/cache/Getter.java b/jena-base/src/main/java/org/apache/jena/atlas/lib/cache/Getter.java new file mode 100644 index 0000000..c9f879c --- /dev/null +++ b/jena-base/src/main/java/org/apache/jena/atlas/lib/cache/Getter.java @@ -0,0 +1,25 @@ +/* + * 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.jena.atlas.lib.cache; + +/** A get interface */ +public interface Getter<K, V> +{ + public V get(K key) ; +}
