http://git-wip-us.apache.org/repos/asf/jena/blob/1320f8db/jena-base/src/main/java/org/apache/jena/atlas/lib/FileOps.java ---------------------------------------------------------------------- diff --git a/jena-base/src/main/java/org/apache/jena/atlas/lib/FileOps.java b/jena-base/src/main/java/org/apache/jena/atlas/lib/FileOps.java new file mode 100644 index 0000000..6862f4a --- /dev/null +++ b/jena-base/src/main/java/org/apache/jena/atlas/lib/FileOps.java @@ -0,0 +1,239 @@ +/* + * 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.File ; +import java.io.FileInputStream ; +import java.io.FileOutputStream ; +import java.io.IOException ; +import java.nio.channels.FileChannel ; + +import org.apache.jena.atlas.AtlasException ; +import org.apache.jena.atlas.io.IO ; +import org.apache.jena.atlas.logging.Log ; + +/** A library of utility operations on files and the filing system */ +public class FileOps { + // Update implementations as standard library functions appear that meet the contract. + private FileOps() {} + + /** + * Delete a file + * + * @param filename + */ + public static void delete(String filename) { + delete(new File(filename), true) ; + } + + /* Delete a file - don't check it worked */ + + public static void deleteSilent(String filename) { + delete(new File(filename), false) ; + } + + public static void delete(File f, boolean reportExistsAfter) { + try { + /* + * Note: On windows, deleting a file which has been memory mapped + * does not delete the file. + */ + f.delete() ; + if ( reportExistsAfter && f.exists() ) + Log.warn(FileOps.class, "delete: *** File still exists: " + f) ; + } + catch (SecurityException ex) { + Log.warn(FileOps.class, "delete: " + f + ": Security exception; " + ex.getMessage()) ; + } + + } + + /** Delete all files in a directory */ + public static void clearDirectory(String dir) { + File d = new File(dir) ; + for ( File f : d.listFiles() ) { + if ( f.isFile() ) + delete(f, false) ; + } + } + + /** Delete all files and directories (recursively) in a directory */ + public static void clearAll(String d) { + clearAll(new File(d)) ; + } + + /** Delete all files and directories (recursively) in a directory */ + public static void clearAll(File d) { + if ( ! d.exists() ) + return ; + + for ( File f : d.listFiles() ) { + if ( ".".equals(f.getName()) || "..".equals(f.getName()) ) + continue ; + if ( f.isDirectory() ) + clearAll(f) ; + f.delete() ; + } + } + + /** See if there are any files in this directory */ + public static boolean existsAnyFiles(String dir) { + File d = new File(dir) ; + File[] entries = d.listFiles() ; + if ( entries == null ) + // Not a directory + return false ; + return entries.length > 0 ; + } + + /** Test for existence */ + public static boolean exists(String path) { + File f = new File(path) ; + return f.exists() ; + } + + /** Test for an empty file */ + public static boolean isEmpty(String filename) { + File f = new File(filename) ; + if ( f.exists() ) + return true ; + if ( f.isFile() ) + return f.length() == 0 ; + throw new AtlasException("Not a file") ; + } + + /** Ensure a directory exists */ + public static void ensureDir(String dirname) { + File dir = new File(dirname) ; + if ( !dir.exists() ) + dir.mkdirs() ; + } + + /** + * Split a file name into path, basename and extension. Nulls returned if + * don't make sense. + */ + public static Tuple<String> splitDirBaseExt(String filename) { + String path = null ; + String basename = filename ; + String ext = null ; + + int j = filename.lastIndexOf('/') ; + if ( j < 0 ) + j = filename.lastIndexOf('\\') ; + + if ( j >= 0 ) { + path = filename.substring(0, j) ; + basename = filename.substring(j + 1) ; + } + + int i = basename.lastIndexOf('.') ; + + if ( i > -1 ) { + ext = basename.substring(i + 1) ; + basename = basename.substring(0, i) ; + } + + return Tuple.createTuple(path, basename, ext) ; + } + + /** + * Split a file name into path and filename. Nulls returned if don't make + * sense. + */ + public static Tuple<String> splitDirFile(String filename) { + String path = null ; + String fn = filename ; + + int j = filename.lastIndexOf('/') ; + if ( j < 0 ) + j = filename.lastIndexOf('\\') ; + + if ( j >= 0 ) { + path = filename.substring(0, j) ; + fn = filename.substring(j + 1) ; + } + return Tuple.createTuple(path, fn) ; + } + + /** Return the basename (no path, no extension) */ + public static String basename(String filename) { + int j = filename.lastIndexOf('/') ; + if ( j < 0 ) + j = filename.lastIndexOf('\\') ; + + String fn = (j >= 0) ? filename.substring(j + 1) : filename ; + int i = fn.lastIndexOf('.') ; + + if ( i > -1 ) + return fn.substring(0, i) ; + return fn ; + } + + /** Return the extension (or "") */ + public static String extension(String filename) { + int iSlash = filename.lastIndexOf('/') ; + int iBack = filename.lastIndexOf('\\') ; + int iExt = filename.lastIndexOf('.') ; + if ( iBack > iSlash ) + iSlash = iBack ; + return iExt > iSlash ? filename.substring(iExt + 1).toLowerCase() : "" ; + } + + public static String fullPath(String filename) { + File f = new File(filename) ; + return f.getAbsolutePath() ; + } + + public static String fullDirectoryPath(String filename) { + File f = new File(filename) ; + if ( f.isDirectory() ) { + return f.getAbsolutePath() ; + } else if ( f.getParentFile() != null ) { + return f.getParentFile().getAbsolutePath() ; + } else { + return f.getAbsolutePath() ; + } + } + + /** Copy a file */ + public static void copyFile(File source, File dest) { + try { + @SuppressWarnings("resource") + FileChannel sourceChannel = new FileInputStream(source).getChannel() ; + @SuppressWarnings("resource") + FileChannel destChannel = new FileOutputStream(dest).getChannel() ; + destChannel.transferFrom(sourceChannel, 0, sourceChannel.size()) ; + sourceChannel.close() ; + destChannel.close() ; + } + catch (IOException ex) { + IO.exception(ex) ; + } + } + + // public static String getExt(String filename) + // { + // int i = filename.lastIndexOf('.') ; + // int j = filename.lastIndexOf('/') ; + // if ( i > j ) + // return filename.substring(i+1) ; + // return null ; + // } +}
http://git-wip-us.apache.org/repos/asf/jena/blob/1320f8db/jena-base/src/main/java/org/apache/jena/atlas/lib/Hex.java ---------------------------------------------------------------------- diff --git a/jena-base/src/main/java/org/apache/jena/atlas/lib/Hex.java b/jena-base/src/main/java/org/apache/jena/atlas/lib/Hex.java new file mode 100644 index 0000000..27ebbb5 --- /dev/null +++ b/jena-base/src/main/java/org/apache/jena/atlas/lib/Hex.java @@ -0,0 +1,97 @@ +/* + * 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 ; + +/** Working in hex ... */ +public class Hex +{ + // No checking, fixed width. + public static int formatUnsignedLongHex(final byte[] b, final int start, final long value, final int width) + { + // Insert from low value end to high value end. + int idx = start+width-1 ; + int w = width ; + long x = value ; + + while ( w > 0 ) + { + int d = (int)(x & 0xF) ; + x = x>>>4 ; // Unsigned shift. + byte ch = Bytes.hexDigitsUC[d] ; + b[idx] = ch ; + w-- ; + idx-- ; + + if ( x == 0 ) + break ; + } + + if ( x != 0 ) + throw new AtlasException("formatUnsignedLongHex: overflow") ; + + while ( w > 0 ) + { + b[idx] = '0' ; + idx-- ; + w-- ; + } + return width ; + } + + // No checking, fixed width. + public static long getLong(byte[] arr, int idx) + { + long x = 0 ; + for ( int i = 0 ; i < 16 ; i++ ) + { + byte c = arr[idx] ; + int v = hexByteToInt(c) ; + x = x << 4 | v ; + idx++ ; + } + return x ; + } + + public static int hexByteToInt(int c) + { + if ( '0' <= c && c <= '9' ) + return c-'0' ; + else if ( 'A' <= c && c <= 'F' ) + return c-'A'+10 ; + else if ( 'a' <= c && c <= 'f' ) + return c-'a'+10 ; + else + throw new IllegalArgumentException("Bad index char : "+c) ; + } + + /** Return the value of the hex digit, or the marker value if not a hex digit.*/ + public static int hexByteToInt(int c, int marker) + { + if ( '0' <= c && c <= '9' ) + return c-'0' ; + else if ( 'A' <= c && c <= 'F' ) + return c-'A'+10 ; + else if ( 'a' <= c && c <= 'f' ) + return c-'a'+10 ; + else + return marker ; + } +} http://git-wip-us.apache.org/repos/asf/jena/blob/1320f8db/jena-base/src/main/java/org/apache/jena/atlas/lib/IRILib.java ---------------------------------------------------------------------- diff --git a/jena-base/src/main/java/org/apache/jena/atlas/lib/IRILib.java b/jena-base/src/main/java/org/apache/jena/atlas/lib/IRILib.java new file mode 100644 index 0000000..daafb74 --- /dev/null +++ b/jena-base/src/main/java/org/apache/jena/atlas/lib/IRILib.java @@ -0,0 +1,243 @@ +/* + * 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.File ; +import java.io.IOException ; + +import org.apache.jena.atlas.AtlasException ; +import org.apache.jena.base.Sys ; + +/** Operations related to IRIs */ +public class IRILib +{ + // http://www.w3.org/TR/xpath-functions/#func-encode-for-uri + // Encodes delimiters. + + /* RFC 3986 + * + * unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~" + * gen-delims = ":" / "/" / "?" / "#" / "[" / "]" / "@" + * sub-delims = "!" / "$" / "&" / "'" / "(" / ")" + / "*" / "+" / "," / ";" / "=" + */ + + private static char uri_reserved[] = + { '!', '*', '"', '\'', '(', ')', ';', ':', '@', '&', + '=', '+', '$', ',', '/', '?', '%', '#', '[', ']' } ; + + // No allowed in URIs + private static char uri_non_chars[] = { '<', '>', '{', '}', '|', '\\', '`', '^', ' ', '\n', '\r', '\t', '£' } ; + + // RFC 2396 + //private static char uri_unwise[] = { '{' , '}', '|', '\\', '^', '[', ']', '`' } ; + + + private static char[] charsComponent = + // reserved, + non-chars + nasties. + { '!', '*', '"', '\'', '(', ')', ';', ':', '@', '&', + '=', '+', '$', ',', '/', '?', '%', '#', '[', ']', + '{', '}', '|', '\\', '`', '^', + ' ', '<', '>', '\n', '\r', '\t', '£' } ; + + private static char[] charsFilename = + // reserved, + non-chars + nasties. + // Leave : (Windows drive charcater) and / (separator) alone + // include SPC. + // Should this include "~"? + { '!', '*', '"', '\'', '(', ')', ';', /*':',*/ '@', '&', + '=', '+', '$', ',', /*'/',*/ '?', '%', '#', '[', ']', + '{', '}', '|', '\\', '`', '^', + ' ', '<', '>', '\n', '\r', '\t'} ; + + private static char[] charsPath = + { // Reserved except leave the separators alone. + '!', '*', '"', '\'', '(', ')', ';', /*':',*/ '@', '&', + '=', '+', '$', ',', /*'/',*/ '?', '%', '#', '[', ']', + '{', '}', '|', '\\', '`', '^', + // Other junk + ' ', '<', '>', '\n', '\r', '\t' } ; + + // The initializers must have run. + static final String cwd ; + static final String cwdURL ; + + // Current directory, with trailing "/" + // This matters for resolution. + static { + String x = new File(".").getAbsolutePath() ; + x = x.substring(0, x.length()-1) ; + cwd = x ; + cwdURL = plainFilenameToURL(cwd) ; + } + + // See also IRIResolver + /** Return a string that is an IRI for the filename.*/ + public static String fileToIRI(File f) { + return filenameToIRI(f.getAbsolutePath()) ; + } + + /** Create a string that is a IRI for the filename. + * <li>The file name may already have {@code file:}. + * <li>The file name may be relative. + * <li>Encode using the rules for a path (e.g. ':' and'/' do not get encoded) + * <li>Non-IRI characters get %-encoded. + */ + public static String filenameToIRI(String fn) { + if ( fn == null ) return cwdURL ; + + if ( fn.length() == 0 ) return cwdURL ; + + if ( fn.startsWith("file:") ) + return normalizeFilenameURI(fn) ; + return plainFilenameToURL(fn) ; + } + + /** Convert a file: IRI to a filename */ + public static String IRIToFilename(String iri) { + if ( ! iri.startsWith("file:") ) + throw new AtlasException("Not a file: URI: "+iri) ; + + String fn ; + if ( iri.startsWith("file:///") ) + fn = iri.substring("file://".length()) ; + else + fn = iri.substring("file:".length()) ; + return decode(fn) ; + } + + /** Convert a plain file name (no file:) to a file: URL */ + private static String plainFilenameToURL(String fn) { + // No "file:" + // Make Absolute filename. + boolean trailingSlash = fn.endsWith("/") ; + File file = new File(fn) ; + + try { fn = file.getCanonicalPath() ; } + catch (IOException e) { fn = file.getAbsolutePath() ; } + + if ( trailingSlash && ! fn.endsWith("/") ) + fn = fn + "/" ; + + if ( Sys.isWindows ) + { + // C:\ => file:///C:/... + if ( fn.length() >= 2 && fn.charAt(1) == ':' ) + // Windows drive letter - already absolute path. + // Make "URI" absolute path + fn = "/"+fn ; + // Convert \ to / + // Maybe should do this on all platforms? i.e consistency. + fn = fn.replace('\\', '/' ) ; + } + + fn = encodeFileURL(fn) ; + return "file://"+fn ; + } + + + /** Sanitize a "file:" URL. Must start "file:" */ + private static String normalizeFilenameURI(String fn) { + if ( ! fn.startsWith("file:/") ) + { + // Relative path. + String fn2 = fn.substring("file:".length()) ; + return plainFilenameToURL(fn2) ; + } + + // Starts file:/// + if ( fn.startsWith("file:///") ) + // Assume it's good and return as-is. + return fn ; + + if ( fn.startsWith("file://") ) + { + String fn2 = fn.substring("file:/".length()) ; // Leave one "/" + return plainFilenameToURL(fn2) ; + } + + // Must be file:/ + String fn2 = fn.substring("file:".length()) ; + return plainFilenameToURL(fn2) ; + } + + /** Encode using the rules for a component (e.g. ':' and '/' get encoded) + * Does not encode non-ASCII characters + */ + public static String encodeUriComponent(String string) { + String encStr = StrUtils.encodeHex(string,'%', charsComponent) ; + return encStr ; + } + + /** Encode using the rules for a file: URL. + * Does not encode non-ASCII characters + */ + public static String encodeFileURL(String string) { + String encStr = StrUtils.encodeHex(string,'%', charsFilename) ; + return encStr ; + } + + /** Encode using the rules for a path (e.g. ':' and '/' do not get encoded) */ + public static String encodeUriPath(String uri) { + // Not perfect. + // Encode path. + // %-encode chars. + uri = StrUtils.encodeHex(uri, '%', charsPath) ; + return uri ; + } + + public static String decode(String string) { + return StrUtils.decodeHex(string, '%') ; + } + + public static String encodeNonASCII(String string) { + if ( ! containsNonASCII(string) ) + return string ; + + byte[] bytes = StrUtils.asUTF8bytes(string) ; + StringBuilder sw = new StringBuilder() ; + for ( byte b : bytes ) + { + // Signed bytes ... + if ( b > 0 ) + { + sw.append( (char) b ); + continue; + } + + int hi = ( b & 0xF0 ) >> 4; + int lo = b & 0xF; + sw.append( '%' ); + sw.append( Chars.hexDigitsUC[hi] ); + sw.append( Chars.hexDigitsUC[lo] ); + } + return sw.toString() ; + } + + public static boolean containsNonASCII(String string){ + boolean clean = true ; + for ( int i = 0 ; i < string.length() ; i++ ) + { + char ch = string.charAt(i) ; + if ( ch >= 127 ) + return true; + } + return false ; + } +} http://git-wip-us.apache.org/repos/asf/jena/blob/1320f8db/jena-base/src/main/java/org/apache/jena/atlas/lib/InternalErrorException.java ---------------------------------------------------------------------- diff --git a/jena-base/src/main/java/org/apache/jena/atlas/lib/InternalErrorException.java b/jena-base/src/main/java/org/apache/jena/atlas/lib/InternalErrorException.java new file mode 100644 index 0000000..b20b2d6 --- /dev/null +++ b/jena-base/src/main/java/org/apache/jena/atlas/lib/InternalErrorException.java @@ -0,0 +1,27 @@ +/* + * 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 InternalErrorException extends RuntimeException +{ + public InternalErrorException() { super() ; } + public InternalErrorException(String msg) { super(msg) ; } + public InternalErrorException(Throwable th) { super(th) ; } + public InternalErrorException(String msg, Throwable th) { super(msg, th) ; } +} http://git-wip-us.apache.org/repos/asf/jena/blob/1320f8db/jena-base/src/main/java/org/apache/jena/atlas/lib/Lib.java ---------------------------------------------------------------------- diff --git a/jena-base/src/main/java/org/apache/jena/atlas/lib/Lib.java b/jena-base/src/main/java/org/apache/jena/atlas/lib/Lib.java new file mode 100644 index 0000000..6c9c442 --- /dev/null +++ b/jena-base/src/main/java/org/apache/jena/atlas/lib/Lib.java @@ -0,0 +1,126 @@ +/* + * 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.List ; +import java.util.zip.Adler32 ; +import java.util.zip.CRC32 ; +import java.util.zip.Checksum ; + +import org.apache.jena.atlas.logging.Log ; + +public class Lib +{ + private Lib() {} + + public static final void sync(Object object) + { + if ( object instanceof Sync ) + ((Sync)object).sync() ; + } + + /** Return true if obj1 and obj are both null or are .equals, else return false */ + public static final <T> boolean equal(T obj1, T obj2) + { + if ( obj1 == null ) + return obj2 == null ; + // obj1 != null + if ( obj2 == null ) + return false ; + return obj1.equals(obj2) ; + } + + /** Return true if obj1 and obj are both null or are .equals, else return false */ + public static final boolean equalsIgnoreCase(String str1, String str2) + { + if ( str1 == null ) + return str2 == null ; + return str1.equalsIgnoreCase(str2) ; + } + + + /** Return true if obj1 and obj are ! equal */ + public static final <T> boolean notEqual(T obj1, T obj2) + { + return ! equal(obj1, obj2) ; + } + + /** Safely return the class short name for an object -- obj.getClass().getSimpleName() */ + static public final String className(Object obj) { + if ( obj == null ) + return "null" ; + return classShortName(obj.getClass()) ; + } + + /** Safely return the class short name for a class */ + static public final String classShortName(Class<? > cls) { + if ( cls == null ) + return "null" ; + return cls.getSimpleName() ; + } + + /** Do two lists have the same elements? */ + public static <T> boolean equalsListAsSet(List<T> list1, List<T> list2) { + if ( list1 == null && list2 == null ) + return true ; + if ( list1 == null ) return false ; + if ( list2 == null ) return false ; + return list1.containsAll(list2) && list2.containsAll(list1) ; + } + + /** HashCode - allow nulls */ + public static final int hashCodeObject(Object obj) { return hashCodeObject(obj, -4) ; } + + /** HashCode - allow nulls */ + public static final int hashCodeObject(Object obj, int nullHashCode) + { + if ( obj == null ) + return nullHashCode ; + return obj.hashCode() ; + } + + public static final void sleep(int milliSeconds) + { + try { Thread.sleep(milliSeconds) ; } + catch (InterruptedException ex) { Log.warn(Lib.class, "interrupted", ex) ; } + } + + /** + * @see CRC32 + */ + public static long crc32(byte[] bytes) + { + return crc(new CRC32(), bytes) ; + } + + /** Faster than CRC32, nearly as good. + * @see Adler32 + */ + public static long adler32(byte[] bytes) + { + return crc(new Adler32(), bytes) ; + } + + private static long crc(Checksum alg, byte[] bytes) + { + alg.reset() ; + alg.update(bytes, 0, bytes.length) ; + return alg.getValue() ; + } +} http://git-wip-us.apache.org/repos/asf/jena/blob/1320f8db/jena-base/src/main/java/org/apache/jena/atlas/lib/ListUtils.java ---------------------------------------------------------------------- diff --git a/jena-base/src/main/java/org/apache/jena/atlas/lib/ListUtils.java b/jena-base/src/main/java/org/apache/jena/atlas/lib/ListUtils.java new file mode 100644 index 0000000..78d591a --- /dev/null +++ b/jena-base/src/main/java/org/apache/jena/atlas/lib/ListUtils.java @@ -0,0 +1,150 @@ +/* + * 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 ; + + +import org.apache.jena.atlas.io.IndentedWriter ; +import org.apache.jena.atlas.iterator.Action ; +import org.apache.jena.atlas.iterator.FilterUnique ; +import org.apache.jena.atlas.iterator.Iter ; +import org.apache.jena.atlas.logging.Log ; + +/** Various things for lists */ +public class ListUtils +{ + private ListUtils() {} + + public static <T> + List<T> unique(List<T> list) + { + Iter<T> iter = Iter.iter(list.iterator()) ; + return iter.filter(new FilterUnique<T>()).toList() ; + } + + public static + List<Integer> asList(int... values) + { + List<Integer> x = new ArrayList<>() ; + for ( int v : values ) + x.add(v) ; + return x ; + } + + public static <T> String str(T[] array) + { + StringBuilder buff = new StringBuilder() ; + String sep = "[" ; + + for ( T anArray : array ) + { + buff.append( sep ); + sep = ", "; + buff.append( anArray ); + } + buff.append("]") ; + return buff.toString() ; + } + + public static String str(int[] array) + { + StringBuilder buff = new StringBuilder() ; + String sep = "[" ; + + for ( int anArray : array ) + { + buff.append( sep ); + sep = ", "; + buff.append( anArray ); + } + buff.append("]") ; + return buff.toString() ; + } + + public static String str(long[] array) + { + StringBuilder buff = new StringBuilder() ; + String sep = "[" ; + + for ( long anArray : array ) + { + buff.append( sep ); + sep = ", "; + buff.append( anArray ); + } + buff.append("]") ; + return buff.toString() ; + } + + public static <T> void print(IndentedWriter out, List<T> list) + { + print(out, list, " ") ; + } + + public static <T> void print(final IndentedWriter out, List<T> list, final String sep) + { + Action<T> output = new Action<T>() { + boolean first = true ; + @Override + public void apply(T item) + { + if ( ! first ) out.print(sep) ; + out.print(item.toString()) ; + first = false ; + } + } ; + Iter.apply(list.iterator(), output) ; + } + + /** Return a list of lists of all the elements of collection in every order + * Easy to run out of heap memory. + */ + static public <T> List<List<T>> permute(List<T> c) + { + if ( c.size() > 5 ) + { + Log.warn(ListUtils.class, "Attempt to permute more than 5 items - think again") ; + return null ; + } + + List<List<T>> x = new ArrayList<>() ; + if ( c.size() == 1 ) + { + x.add(c) ; + return x ; + } + + for ( T obj : c ) + { + List<T> c2 = new ArrayList<>(c) ; + c2.remove(obj) ; + List<List<T>> x2 = permute(c2) ; + // For each list returned + for ( List<T> x3 : x2 ) + { + // Gives a more expected ordering + x3.add(0,obj) ; + x.add(x3) ; + } + } + return x ; + } +} http://git-wip-us.apache.org/repos/asf/jena/blob/1320f8db/jena-base/src/main/java/org/apache/jena/atlas/lib/Map2.java ---------------------------------------------------------------------- diff --git a/jena-base/src/main/java/org/apache/jena/atlas/lib/Map2.java b/jena-base/src/main/java/org/apache/jena/atlas/lib/Map2.java new file mode 100644 index 0000000..75697e0 --- /dev/null +++ b/jena-base/src/main/java/org/apache/jena/atlas/lib/Map2.java @@ -0,0 +1,104 @@ +/* + * 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.Iterator ; +import java.util.Map ; + +import org.apache.jena.atlas.iterator.Iter ; + + +/** + * A map with parent sharing. New entries go into a map but lookup is passed to + * the parent map if nothing is found at this level. + */ +public class Map2<K, V> implements Iterable<K> +{ + private final Map<K, V> map1 ; + private final Map2<K, V> map2 ; + + public Map2(Map<K,V> map1, Map2<K,V> map2) + { + this.map1 = map1 ; + this.map2 = map2 ; + } + + public boolean containsKey(K key) + { + if ( map1.containsKey(key) ) + return true ; + if ( map2 != null ) + return map2.containsKey(key) ; + return false; + } + +// public boolean containsValue(V value) +// { +// if ( map1.containsValue(value) ) +// return true ; +// if ( map2 != null ) +// return map2.containsValue(value) ; +// return false; +// } + + public V get(K key) + { + V v = map1.get(key) ; + if ( v != null ) return v ; + if ( map2 != null ) + return map2.get(key) ; + return null ; + } + + public void put(K key, V value) + { + if ( map2 != null && map2.containsKey(key) ) + throw new IllegalArgumentException("Parent map already contains "+key) ; + map1.put(key, value) ; + } + + // The keys. + @Override + public Iterator<K> iterator() + { + Iter<K> iter1 = Iter.iter(map1.keySet().iterator()) ; + if ( map2 == null ) + return iter1 ; + return iter1.append(map2.iterator()) ; + } + + public boolean isEmpty() + { + boolean x = map1.isEmpty() ; + if ( ! x ) return false ; + if ( map2 != null ) + return map2.isEmpty() ; + return true ; + } + + public int size() + { + int x = map1.size() ; + if ( map2 != null ) + x += map2.size(); + return x ; + } + +} http://git-wip-us.apache.org/repos/asf/jena/blob/1320f8db/jena-base/src/main/java/org/apache/jena/atlas/lib/MapUtils.java ---------------------------------------------------------------------- diff --git a/jena-base/src/main/java/org/apache/jena/atlas/lib/MapUtils.java b/jena-base/src/main/java/org/apache/jena/atlas/lib/MapUtils.java new file mode 100644 index 0000000..7999a25 --- /dev/null +++ b/jena-base/src/main/java/org/apache/jena/atlas/lib/MapUtils.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.util.Map ; + +/** Map specific functions */ +public class MapUtils +{ + private MapUtils() {} + + public static <K, V> void apply(Map<K, V> map, ActionKeyValue<K, V> action) + { + for ( Map.Entry<K,V> entry : map.entrySet() ) + action.apply(entry.getKey(), entry.getValue()) ; + } + + public static <T> void increment(Map<T, Integer> countMap, T key) + { increment(countMap, key, 1) ; } + + public static <T> void increment(Map<T, Integer> countMap, T key, int incr) + { + Integer integer = countMap.get(key) ; + if ( integer == null ) + countMap.put(key, incr) ; + else + countMap.put(key, integer+incr) ; + } +} http://git-wip-us.apache.org/repos/asf/jena/blob/1320f8db/jena-base/src/main/java/org/apache/jena/atlas/lib/MultiMap.java ---------------------------------------------------------------------- diff --git a/jena-base/src/main/java/org/apache/jena/atlas/lib/MultiMap.java b/jena-base/src/main/java/org/apache/jena/atlas/lib/MultiMap.java new file mode 100644 index 0000000..2782ea6 --- /dev/null +++ b/jena-base/src/main/java/org/apache/jena/atlas/lib/MultiMap.java @@ -0,0 +1,146 @@ +/* + * 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.* ; + +import org.apache.jena.atlas.iterator.IteratorConcat ; + +/* Map from K to collection of V */ + +public abstract class MultiMap<K, V> +{ + private Map<K, Collection<V>> map = new HashMap<>() ; + + protected abstract Collection<V> createCollection() ; + + public static <K, V> MultiMapToList<K, V> createMapList() { return new MultiMapToList<>() ; } + public static <K, V> MultiMapToSet<K, V> createMapSet() { return new MultiMapToSet<>() ; } + + protected MultiMap() { } + + protected Collection<V> getByKey(K key) { + return map.get(key) ; + } + + public abstract Collection<V> get(K key) ; + + public V getOne(K key) { + Collection<V> c = map.get(key) ; + if ( c == null || c.size() == 0 ) + return null ; + return c.iterator().next() ; + } + + public void putAll(K key, @SuppressWarnings("unchecked") V ... values) + { + for ( V v : values) + put(key, v) ; + } + + public void put(K key, V value) + { + Collection<V> x = map.get(key) ; + if ( x == null ) + { + x = createCollection() ; + map.put(key, x) ; + } + x.add(value) ; + } + + public void remove(K key, V value) { + if ( map.containsKey(key)) + map.get(key).remove(value) ; + } + public void removeKey(K key) { map.remove(key) ; } + + protected Collection<V> valuesForKey(K key) { return map.get(key); } + public abstract Collection<V> values(K key) ; + public abstract Collection<V> values() ; + + public boolean containsKey(K key) { return map.containsKey(key) ; } + + public Set<K> keys() { return map.keySet() ; } + + public void clear() { map.clear() ; } + + public boolean isEmpty() { return map.isEmpty() ; } + + /** Does not materialise the contents */ + public Iterator<V> flatten() + { + IteratorConcat<V> all = new IteratorConcat<>() ; + for ( K k : map.keySet() ) + { + Collection<V> x = map.get(k) ; + all.add(x.iterator()) ; + } + return all ; + } + + @Override + public boolean equals(Object obj) { + if ( this == obj ) + return true ; + if ( obj == null ) + return false ; + if ( getClass() != obj.getClass() ) + return false ; + MultiMap<?,?> other = (MultiMap<?,?>)obj ; + if ( map == null ) { + if ( other.map != null ) + return false ; + } else if ( !map.equals(other.map) ) + return false ; + return true ; + } + + @Override + public int hashCode() { return map.hashCode()^ 0x01010101 ; } + + @Override + public String toString() + { + StringBuilder sb = new StringBuilder() ; + sb.append("{ ") ; + boolean firstKey = true ; + for ( K key : keys() ) + { + if ( ! firstKey ) + sb.append(", ") ; + firstKey = false ; + sb.append(key) ; + sb.append(" => [") ; + boolean firstValue = true ; + for ( V value : values(key) ) + { + if ( firstValue ) + sb.append(" ") ; + else + sb.append(", ") ; + sb.append(value) ; + firstValue = false ; + } + sb.append(" ] ") ; + } + sb.append("}") ; + return sb.toString() ; + } +} http://git-wip-us.apache.org/repos/asf/jena/blob/1320f8db/jena-base/src/main/java/org/apache/jena/atlas/lib/MultiMapToList.java ---------------------------------------------------------------------- diff --git a/jena-base/src/main/java/org/apache/jena/atlas/lib/MultiMapToList.java b/jena-base/src/main/java/org/apache/jena/atlas/lib/MultiMapToList.java new file mode 100644 index 0000000..ac1ba70 --- /dev/null +++ b/jena-base/src/main/java/org/apache/jena/atlas/lib/MultiMapToList.java @@ -0,0 +1,43 @@ +/** + * 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.Collection ; +import java.util.List ; + +import org.apache.jena.atlas.iterator.Iter ; + +public class MultiMapToList<K,V> extends MultiMap<K,V> { + public static <K, V> MultiMapToList<K, V> create() { return new MultiMapToList<>() ; } + + @Override + protected Collection<V> createCollection() { + return new ArrayList<>() ; + } + + @Override + public List<V> get(K key) { return (List<V>)getByKey(key); } + + @Override + public List<V> values(K key) { return (List<V>)valuesForKey(key); } + + @Override + public List<V> values() { return Iter.toList(flatten()) ; } +} http://git-wip-us.apache.org/repos/asf/jena/blob/1320f8db/jena-base/src/main/java/org/apache/jena/atlas/lib/MultiMapToSet.java ---------------------------------------------------------------------- diff --git a/jena-base/src/main/java/org/apache/jena/atlas/lib/MultiMapToSet.java b/jena-base/src/main/java/org/apache/jena/atlas/lib/MultiMapToSet.java new file mode 100644 index 0000000..b89e05b --- /dev/null +++ b/jena-base/src/main/java/org/apache/jena/atlas/lib/MultiMapToSet.java @@ -0,0 +1,47 @@ +/** + * 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 ; +import java.util.HashSet ; +import java.util.Set ; + +import org.apache.jena.atlas.iterator.Iter ; + +public class MultiMapToSet<K,V> extends MultiMap<K,V> { + public static <K, V> MultiMapToSet<K, V> create() { return new MultiMapToSet<>() ; } + + @Override + protected Collection<V> createCollection() + { + return new HashSet<>() ; + } + + @Override + public Set<V> get(K key) { return (Set<V>)getByKey(key) ; } + + @Override + public Set<V> values(K key) { return (Set<V>)valuesForKey(key); } + + @Override + public Set<V> values() { return Iter.toSet(flatten()) ; } + + +} + http://git-wip-us.apache.org/repos/asf/jena/blob/1320f8db/jena-base/src/main/java/org/apache/jena/atlas/lib/MultiSet.java ---------------------------------------------------------------------- diff --git a/jena-base/src/main/java/org/apache/jena/atlas/lib/MultiSet.java b/jena-base/src/main/java/org/apache/jena/atlas/lib/MultiSet.java new file mode 100644 index 0000000..3701042 --- /dev/null +++ b/jena-base/src/main/java/org/apache/jena/atlas/lib/MultiSet.java @@ -0,0 +1,218 @@ +/* + * 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.HashMap ; +import java.util.Iterator ; +import java.util.List ; +import java.util.Map ; +import java.util.NoSuchElementException ; + +/** A MultiSet - also known as a Bag + */ + +public class MultiSet<T> implements Iterable<T> +{ + private Map<T,RefLong> map = new HashMap<>() ; + private int multiSetSize = 0 ; + + private RefLong _get(T obj) + { + RefLong z = map.get(obj) ; + if ( z == null ) + { + z = new RefLong(0) ; + map.put(obj, z) ; + } + return z ; + } + + /** Does it contain any elements at all? */ + public boolean isEmpty() { return map.isEmpty() ; } + + /** Does it contain the object? */ + public boolean contains(T obj) { return map.containsKey(obj) ; } + + /** Yield one object per element (i.e without counts) */ + public Iterator<T> elements() { return map.keySet().iterator() ; } + + /** Add an object */ + public void add(T obj) { _get(obj).inc(); multiSetSize++ ; } + + /** Add an object, with cardinality n */ + public void add(T obj, long n) + { + if ( n <= 0 ) return ; + _get(obj).add(n) ; + multiSetSize += n ; + } + + /** Remove one occurrence of the object from the multiset */ + public void remove(T obj) + { + RefLong x = map.get(obj) ; + if ( x == null ) return ; + x.dec() ; + multiSetSize-- ; + if ( x.value() == 0 ) + map.remove(obj) ; + } + + /** Remove N occurrences of the object from the multiset */ + public void remove(T obj, long n) + { + RefLong x = map.get(obj) ; + if ( x == null ) return ; + long z = x.value() ; + if ( z < n ) + n = z ; + x.subtract(n) ; + multiSetSize -= n ; + if ( x.value() <= 0 ) + map.remove(obj) ; + } + + + /** Remove all occurrences of the object in themultiset */ + public void removeAll(T obj) + { + RefLong x = map.get(obj) ; + if ( x == null ) + return ; + multiSetSize -= x.value() ; + map.remove(obj) ; + } + + /* Remove everything */ + public void clear() { map.clear() ; multiSetSize = 0 ; } + + + /** Get the count of the number of times the object appears in the multiset - i.e. it's cardinality. + * Returns zero when not present. + */ + public long count(T obj) + { + if ( ! map.containsKey(obj) ) return 0 ; + return map.get(obj).value() ; + } + + public int size() + { +// int count = 0 ; +// for ( Map.Entry<T, RefLong> e : map.entrySet() ) +// count += e.getValue().value() ; +// //return count ; +// if ( count != multiSetSize ) +// { +// Log.warn(this, "Mismatch") ; +// return count ; +// } + + return multiSetSize ; + } + + private Iterator<T> iterator1() + { + // CRUDE + List<T> expanded = new ArrayList<>() ; + for ( Map.Entry<T, RefLong> e : map.entrySet() ) + { + for ( int i = 0 ; i < e.getValue().value() ; i++ ) + expanded.add(e.getKey()) ; + } + + return expanded.iterator() ; + } + + @Override + public Iterator<T> iterator() + { + return new Iterator<T>() { + + Iterator<T> keys = map.keySet().iterator() ; + T key = null ; + long keyCount = 0 ; + T slot = null ; + + @Override + public boolean hasNext() + { + if ( slot != null ) + return true ; + + if ( keys == null ) + return false ; + + if ( key != null ) + { + if ( keyCount < count(key) ) + { + keyCount++ ; + slot = key ; + return true ; + } + // End of this key. + key = null ; + } + + if ( keys.hasNext() ) + { + key = keys.next() ; + keyCount = 1 ; + slot = key ; + return true ; + } + keys = null ; + return false ; + } + + @Override + public T next() + { + if ( ! hasNext() ) throw new NoSuchElementException() ; + T x = slot ; + slot = null ; + return x ; + } + + @Override + public void remove() + { throw new UnsupportedOperationException() ; } + } ; + } + + @Override + public String toString() + { + StringBuilder sb = new StringBuilder() ; + sb.append("{") ; + String sep = "" ; + for ( Map.Entry<T, RefLong> e : map.entrySet() ) + { + sb.append(sep) ; + sep = ", " ; + sb.append(e.getKey().toString()) ; + sb.append("=") ; + sb.append(Long.toString(e.getValue().value())) ; + } + sb.append("}") ; + return sb.toString() ; + } +} http://git-wip-us.apache.org/repos/asf/jena/blob/1320f8db/jena-base/src/main/java/org/apache/jena/atlas/lib/NotImplemented.java ---------------------------------------------------------------------- diff --git a/jena-base/src/main/java/org/apache/jena/atlas/lib/NotImplemented.java b/jena-base/src/main/java/org/apache/jena/atlas/lib/NotImplemented.java new file mode 100644 index 0000000..b7e91f1 --- /dev/null +++ b/jena-base/src/main/java/org/apache/jena/atlas/lib/NotImplemented.java @@ -0,0 +1,27 @@ +/* + * 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 NotImplemented extends InternalErrorException +{ + public NotImplemented() { super() ; } + public NotImplemented(String msg) { super(msg) ; } + public NotImplemented(Throwable th) { super(th) ; } + public NotImplemented(String msg, Throwable th) { super(msg, th) ; } +} http://git-wip-us.apache.org/repos/asf/jena/blob/1320f8db/jena-base/src/main/java/org/apache/jena/atlas/lib/NumberUtils.java ---------------------------------------------------------------------- diff --git a/jena-base/src/main/java/org/apache/jena/atlas/lib/NumberUtils.java b/jena-base/src/main/java/org/apache/jena/atlas/lib/NumberUtils.java new file mode 100644 index 0000000..4f51beb --- /dev/null +++ b/jena-base/src/main/java/org/apache/jena/atlas/lib/NumberUtils.java @@ -0,0 +1,133 @@ +/* + * 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 ; + +public class NumberUtils +{ + // Maximum length of a length 1,2,3,4... + private final static int [] maxTable = { + 9, 99, 999, 9999, 99999, 999999, 9999999, + 99999999, 999999999, Integer.MAX_VALUE }; + + /** Fast, but basic, integer to StringBuilder */ + public static void formatInt(StringBuilder sb, int value) + { + // SeeAlso Integer.toString. + int len = length(value) ; + formatInt(sb, value, len, false) ; + } + + /** Fast, but basic, integer to StringBuilder : always signed */ + public static void formatSignedInt(StringBuilder sb, int value) + { + int len = length(value) ; + if ( value >= 0 ) + len++ ; + formatInt(sb, value, len, true) ; + } + + static int length(int x) + { + if ( x < 0 ) + return length(-x)+1 ; + + for (int i=0; ; i++) + if (x <= maxTable[i]) + return i+1; + } + + /** Place a fixed width representation of a non-negative int into the string buffer */ + public static void formatInt(StringBuilder sb, int value, int width) + { + formatInt(sb, value, width, false) ; + } + + /** Place a fixed width representation into the string buffer : always signed. */ + public static void formatSignedInt(StringBuilder sb, int value, int width) + { + formatInt(sb, value, width, true) ; + } + + /** Format an integer, which may be signed */ + public static void formatInt(StringBuilder sb, int value, int width, boolean signAlways) + { + boolean negative = (value < 0 ) ; + + if ( negative ) + { + value = -value ; + width -- ; + sb.append('-') ; + } + else if ( signAlways ) + { + width -- ; + sb.append('+') ; + } + + formatUnsignedInt(sb, value, width) ; + } + + /** Place a fixed width representation into the string buffer : never signed. */ + public static void formatUnsignedInt(StringBuilder sb, int value, int width) + { + char chars[] = new char[width] ; + formatUnsignedInt$(chars, value, width) ; + + // Append - the buffer was filled backwards. + for ( int i = 0 ; i < width ; i++ ) + // Un-backwards. + sb.append(chars[width-1-i]) ; + + } + + // No checking. char[] filled backwards + private static int formatUnsignedInt$(char[] b, int x, int width) + { + // x >= 0 + // Inserts chars backwards + int idx = 0 ; + while ( width > 0 ) + { + int i = x%10 ; + char ch = Chars.digits10[i] ; + b[idx] = ch ; + width-- ; + idx++ ; + + x = x / 10 ; + if ( x == 0 ) + break ; + } + + if ( x != 0 ) + throw new AtlasException("formatInt: overflow[x="+x+", width="+width+"]") ; + + while ( width > 0 ) + { + b[idx] = '0' ; + idx++ ; + width-- ; + } + return width ; + } + +} http://git-wip-us.apache.org/repos/asf/jena/blob/1320f8db/jena-base/src/main/java/org/apache/jena/atlas/lib/Pair.java ---------------------------------------------------------------------- diff --git a/jena-base/src/main/java/org/apache/jena/atlas/lib/Pair.java b/jena-base/src/main/java/org/apache/jena/atlas/lib/Pair.java new file mode 100644 index 0000000..4f3b055 --- /dev/null +++ b/jena-base/src/main/java/org/apache/jena/atlas/lib/Pair.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; + +import static org.apache.jena.atlas.lib.Lib.hashCodeObject ; +import static org.apache.jena.atlas.lib.StrUtils.str ; + +public class Pair<A, B> +{ + public static <L, R> Pair<L,R> create(L x, R y) { return new Pair<>(x,y) ; } + + final A a ; + final B b ; + public Pair(A a, B b) { this.a = a; this.b = b ; } + + public A getLeft() { return a ; } + public B getRight() { return b ; } + + public A car() { return a ; } + public B cdr() { return b ; } + + @Override + public int hashCode() + { + return hashCodeObject(car()) ^ hashCodeObject(cdr())<<1 ; + } + + @Override + public boolean equals(Object other) + { + if ( this == other ) return true ; + + // If it's a pair of a different <A,B> then .equals + // Pair<A,B>(null,null) is equal to Pair<C,D>(null ,null) + // Type erasure makes this hard to check otherwise. + // Use class X extends Pair<A,B> and implement .equals to do + // instanceof then call super.equals. + + if( ! ( other instanceof Pair<?,?> ) ) return false ; + Pair<?,?> p2 = (Pair<?,?>)other ; + return Lib.equal(car(), p2.car()) && Lib.equal(cdr(), p2.cdr()) ; + } + + @Override + public String toString() { return "("+str(a)+", "+str(b)+")" ; } +} http://git-wip-us.apache.org/repos/asf/jena/blob/1320f8db/jena-base/src/main/java/org/apache/jena/atlas/lib/Pool.java ---------------------------------------------------------------------- diff --git a/jena-base/src/main/java/org/apache/jena/atlas/lib/Pool.java b/jena-base/src/main/java/org/apache/jena/atlas/lib/Pool.java new file mode 100644 index 0000000..f28939e --- /dev/null +++ b/jena-base/src/main/java/org/apache/jena/atlas/lib/Pool.java @@ -0,0 +1,30 @@ +/* + * 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 Pool<T> +{ + public abstract void put(T item) ; + + /** Get an item from the pool - return null if the pool is empty */ + public abstract T get() ; + + public abstract boolean isEmpty() ; + +} http://git-wip-us.apache.org/repos/asf/jena/blob/1320f8db/jena-base/src/main/java/org/apache/jena/atlas/lib/PoolBase.java ---------------------------------------------------------------------- diff --git a/jena-base/src/main/java/org/apache/jena/atlas/lib/PoolBase.java b/jena-base/src/main/java/org/apache/jena/atlas/lib/PoolBase.java new file mode 100644 index 0000000..c6cb505 --- /dev/null +++ b/jena-base/src/main/java/org/apache/jena/atlas/lib/PoolBase.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 java.util.ArrayDeque ; + +/** A Pool of objects. Base implements a non-blocking pool (returns null on no entry) + * with infinite upper bound. Set effective size by creating the right number of + * entries when created. + */ +public class PoolBase<T> implements Pool<T> +{ + // For convenience we operate a LIFO policy. + // This not part of the extenal contract of a "pool" + + ArrayDeque<T> pool = new ArrayDeque<>(); + int maxSize = -1 ; // Unbounded + + public PoolBase() {} + //public Pool(int maxSize) { this.maxSize = maxSize ; } + + @Override + public void put(T item) + { + // Currently, unbounded + if ( maxSize >= 0 && pool.size() == 0 ) + {} + pool.push(item) ; + } + + /** Get an item from the pool - return null if the pool is empty */ + @Override + public T get() + { + if ( pool.size() == 0 ) return null ; + return pool.pop(); + } + + @Override + public boolean isEmpty() { return pool.size() == 0 ; } +} http://git-wip-us.apache.org/repos/asf/jena/blob/1320f8db/jena-base/src/main/java/org/apache/jena/atlas/lib/PoolSync.java ---------------------------------------------------------------------- diff --git a/jena-base/src/main/java/org/apache/jena/atlas/lib/PoolSync.java b/jena-base/src/main/java/org/apache/jena/atlas/lib/PoolSync.java new file mode 100644 index 0000000..10e0a6a --- /dev/null +++ b/jena-base/src/main/java/org/apache/jena/atlas/lib/PoolSync.java @@ -0,0 +1,53 @@ +/* + * 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; + + +/** Synchronization wrapper for a pool */ +public class PoolSync<T> implements Pool<T> +{ + private Pool<T> pool ; + + public static <T> Pool<T> create(Pool<T> pool) + { + if ( pool instanceof PoolSync<?>) + { + PoolSync<T> p = (PoolSync<T>)pool ; + return p ; + } + return new PoolSync<>(pool) ; + } + + public PoolSync(Pool<T> pool) { this.pool = pool ; } + + @Override + public final synchronized void put(T item) + { + pool.put(item) ; + } + + @Override + public final synchronized T get() + { + return pool.get(); + } + + @Override + public final synchronized boolean isEmpty() { return pool.isEmpty() ; } +} http://git-wip-us.apache.org/repos/asf/jena/blob/1320f8db/jena-base/src/main/java/org/apache/jena/atlas/lib/Problem.java ---------------------------------------------------------------------- diff --git a/jena-base/src/main/java/org/apache/jena/atlas/lib/Problem.java b/jena-base/src/main/java/org/apache/jena/atlas/lib/Problem.java new file mode 100644 index 0000000..d571fe7 --- /dev/null +++ b/jena-base/src/main/java/org/apache/jena/atlas/lib/Problem.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; + +public class Problem extends RuntimeException +{ + public Problem(String msg) { super(msg) ; } + public Problem(String msg, Throwable th) { super(msg, th) ; } +} http://git-wip-us.apache.org/repos/asf/jena/blob/1320f8db/jena-base/src/main/java/org/apache/jena/atlas/lib/PropertiesSorted.java ---------------------------------------------------------------------- diff --git a/jena-base/src/main/java/org/apache/jena/atlas/lib/PropertiesSorted.java b/jena-base/src/main/java/org/apache/jena/atlas/lib/PropertiesSorted.java new file mode 100644 index 0000000..75060ee --- /dev/null +++ b/jena-base/src/main/java/org/apache/jena/atlas/lib/PropertiesSorted.java @@ -0,0 +1,87 @@ +/* + * 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.Comparator ; +import java.util.Enumeration ; +import java.util.Iterator ; +import java.util.List ; +import java.util.Properties ; + +/** Sorted output */ +public class PropertiesSorted extends Properties +{ + private Comparator<String> comparator = null ; + + //public SortedProperties() { super() ; } + + public PropertiesSorted(Comparator<String> comparator) + { + super() ; + this.comparator = comparator ; + } + + + @SuppressWarnings({"unchecked", "rawtypes"}) + @Override + public synchronized Enumeration<Object> keys() + { + // Old world - enumeration, untyped. But we know they are strings (Propetries hides non-strings in get) + Enumeration<Object> keys = super.keys() ; + List<String> keys2 = new ArrayList<>(super.size()) ; + + for( ; keys.hasMoreElements() ; ) + { + Object obj = keys.nextElement() ; + if ( obj instanceof String ) + keys2.add((String)obj); + } + // Keys are comparable because they are strings. + if ( comparator == null ) + Collections.sort(keys2); + else + Collections.sort(keys2, comparator) ; + + return new IteratorToEnumeration(keys2.listIterator()) ; + } + + static class IteratorToEnumeration<T> implements Enumeration<T> + { + private Iterator<T> iterator ; + + public IteratorToEnumeration(Iterator<T> iterator) + { + this.iterator = iterator ; + } + + @Override + public boolean hasMoreElements() + { + return iterator.hasNext() ; + } + + @Override + public T nextElement() + { + return iterator.next(); + } + } +} http://git-wip-us.apache.org/repos/asf/jena/blob/1320f8db/jena-base/src/main/java/org/apache/jena/atlas/lib/PropertyUtils.java ---------------------------------------------------------------------- diff --git a/jena-base/src/main/java/org/apache/jena/atlas/lib/PropertyUtils.java b/jena-base/src/main/java/org/apache/jena/atlas/lib/PropertyUtils.java new file mode 100644 index 0000000..d4ac5b7 --- /dev/null +++ b/jena-base/src/main/java/org/apache/jena/atlas/lib/PropertyUtils.java @@ -0,0 +1,143 @@ +/* + * 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.* ; +import java.util.Objects ; +import java.util.Properties ; + +import org.apache.jena.atlas.AtlasException ; +import org.apache.jena.atlas.io.IO ; + +public class PropertyUtils { + /** Load properties from a file if the file exists */ + static public Properties loadFromFile(String filename) throws IOException { + Properties properties = new Properties() ; + loadFromFile(properties, filename) ; + return properties ; + } + + /** Load properties from a file if the file exists */ + static public void loadFromFile(Properties properties, String filename) throws IOException { + Objects.requireNonNull(filename, "File name must not be null") ; + if ( "-".equals(filename) ) + throw new IllegalArgumentException("Filename is \"-\" (stdin not supported)") ; + + try (InputStream in = new FileInputStream(filename); Reader r = IO.asBufferedUTF8(in);) { + properties.load(r) ; + } + } + + static public void storeToFile(Properties properties, String comment, String filename) throws IOException { + String str = comment ; + if ( str == null ) + str = filename ; + try (FileOutputStream fos = new FileOutputStream(filename)) { + Writer w = IO.asBufferedUTF8(fos) ; + properties.store(w, "Metadata: " + str) ; + w.flush() ; + } + } + + public static int getPropertyAsInteger(Properties properties, String key) { + String x = properties.getProperty(key) ; + if ( x == null ) + throw new AtlasException("No such property key: " + key) ; + return Integer.parseInt(x) ; + } + + public static int getPropertyAsInteger(Properties properties, String key, int defaultValue) { + String x = properties.getProperty(key) ; + if ( x == null ) + return defaultValue ; + return Integer.parseInt(x) ; + } + + public static boolean getPropertyAsBoolean(Properties properties, String key, boolean dftValue) { + String x = properties.getProperty(key) ; + if ( x == null ) + return dftValue ; + if ( x.equalsIgnoreCase("true") ) + return true ; + if ( x.equalsIgnoreCase("false") ) + return true ; + throw new AtlasException("Value '" + x + "'not recognized for " + key) ; + } + + public static Boolean getPropertyAsBoolean(Properties properties, String key) { + String x = properties.getProperty(key) ; + if ( x == null ) + throw new AtlasException("No such property key: " + key) ; + if ( x.equalsIgnoreCase("true") ) + return true ; + if ( x.equalsIgnoreCase("false") ) + return true ; + throw new AtlasException("Value '" + x + "'not recognized for " + key) ; + } + + /** Test whether a property has a value. Null tests equal to not present. */ + public boolean propertyEquals(Properties properties, String key, String value) { + return Lib.equal(properties.getProperty(key), value) ; + } + + /** Set property if not already set. */ + public void ensurePropertySet(Properties properties, String key, String expected) { + getOrSetDefault(properties, key, expected) ; + } + + /** + * Get property or the default value - also set the default value if not + * present + */ + public String getOrSetDefault(Properties properties, String key, String expected) { + String x = properties.getProperty(key) ; + if ( x == null ) { + properties.setProperty(key, expected) ; + x = expected ; + } + return x ; + } + + /** Check property is an expected value or set if missing */ + public void checkOrSetProperty(Properties properties, String key, String expected) { + String x = properties.getProperty(key) ; + if ( x == null ) { + properties.setProperty(key, expected) ; + return ; + } + if ( x.equals(expected) ) + return ; + + inconsistent(properties, key, x, expected) ; + } + + /** Check property has the vakue given - throw exception if not. */ + public void checkMetadata(Properties properties, String key, String expected) { + String value = properties.getProperty(key) ; + + if ( !Lib.equal(value, value) ) + inconsistent(properties, key, value, expected) ; + } + + private void inconsistent(Properties properties, String key, String actual, String expected) { + String msg = String.format("Inconsistent: key=%s value=%s expected=%s", key, (actual == null ? "<null>" : actual), + (expected == null ? "<null>" : expected)) ; + throw new AtlasException(msg) ; + } + +} http://git-wip-us.apache.org/repos/asf/jena/blob/1320f8db/jena-base/src/main/java/org/apache/jena/atlas/lib/RandomLib.java ---------------------------------------------------------------------- diff --git a/jena-base/src/main/java/org/apache/jena/atlas/lib/RandomLib.java b/jena-base/src/main/java/org/apache/jena/atlas/lib/RandomLib.java new file mode 100644 index 0000000..d2b3516 --- /dev/null +++ b/jena-base/src/main/java/org/apache/jena/atlas/lib/RandomLib.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 java.security.SecureRandom ; +import java.util.Random ; + +public class RandomLib +{ + private RandomLib() {} + + /** Single instance, pure random generator */ + public static final Random random = new SecureRandom() ; + + /** Random numbers, good seed, cheaper allocation */ + public static final Random qrandom = randInit() ; + + private static Random randInit() + { + // Cheap random numbers, well seeded. + int seed = random.nextInt() ; + return new Random(seed) ; + } + +} http://git-wip-us.apache.org/repos/asf/jena/blob/1320f8db/jena-base/src/main/java/org/apache/jena/atlas/lib/Ref.java ---------------------------------------------------------------------- diff --git a/jena-base/src/main/java/org/apache/jena/atlas/lib/Ref.java b/jena-base/src/main/java/org/apache/jena/atlas/lib/Ref.java new file mode 100644 index 0000000..e25b145 --- /dev/null +++ b/jena-base/src/main/java/org/apache/jena/atlas/lib/Ref.java @@ -0,0 +1,54 @@ +/* + * 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; + + +/** A mutable container */ +public class Ref<T> +{ + private T value ; + + public T getValue() { return value; } + + public Ref(T initial) + { setValue(initial); } + + public void setValue(T value) + { this.value = value; } + + + // hashCode and equality are defined on object pointers. +// @Override +// public int hashCode() { return value.hashCode()^0x1 ; } +// +// @Override +// public boolean equals(Object other) +// { +// if ( !( other instanceof Ref ) ) +// return false ; +// Ref<?> r = (Ref<?>)other ; +// return Lib.equals(value, r.value) ; +// } + + @Override + public String toString() + { + return "ref:"+value.toString() ; + } +} http://git-wip-us.apache.org/repos/asf/jena/blob/1320f8db/jena-base/src/main/java/org/apache/jena/atlas/lib/RefLong.java ---------------------------------------------------------------------- diff --git a/jena-base/src/main/java/org/apache/jena/atlas/lib/RefLong.java b/jena-base/src/main/java/org/apache/jena/atlas/lib/RefLong.java new file mode 100644 index 0000000..30dc663 --- /dev/null +++ b/jena-base/src/main/java/org/apache/jena/atlas/lib/RefLong.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; + +public final class RefLong +{ + private long value ; + public RefLong() { this(0) ; } + public RefLong(long v) { value = v ; } + public long value() { return value ; } + public void inc() { value++ ; } + public void dec() { --value ; } + public long getAndInc() { return value++ ; } + public long incAndGet() { return ++value ; } + public long getAndDec() { return value-- ; } + public long decAndGet() { return --value ; } + public void add(long v) { value += v ; } + public void subtract(long v) { value -= v ; } + public void set(long v) { value = v ; } + @Override public String toString() { return "Ref:"+Long.toString(value) ; } + // hashCode and equals are Object equality - this is a mutable object +} http://git-wip-us.apache.org/repos/asf/jena/blob/1320f8db/jena-base/src/main/java/org/apache/jena/atlas/lib/Registry.java ---------------------------------------------------------------------- diff --git a/jena-base/src/main/java/org/apache/jena/atlas/lib/Registry.java b/jena-base/src/main/java/org/apache/jena/atlas/lib/Registry.java new file mode 100644 index 0000000..b1e0d74 --- /dev/null +++ b/jena-base/src/main/java/org/apache/jena/atlas/lib/Registry.java @@ -0,0 +1,39 @@ +/* + * 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 ; +import java.util.Map ; +import java.util.concurrent.ConcurrentHashMap ; + +public class Registry<K,T> +{ + protected Map<K, T> registry = new ConcurrentHashMap<>() ; + + public Registry() {} + + public void put(K key, T value) { registry.put(key, value) ; } + public T get(K key) { return registry.get(key) ; } + public boolean isRegistered(K key) { return registry.containsKey(key) ; } + public void remove(K key) { registry.remove(key) ; } + public Collection<K> keys() { return registry.keySet() ; } + //public Iterator<String> keys() { return registry.keySet().iterator() ; } + public int size() { return registry.size() ; } + public boolean isEmpty() { return registry.isEmpty() ; } +} http://git-wip-us.apache.org/repos/asf/jena/blob/1320f8db/jena-base/src/main/java/org/apache/jena/atlas/lib/ReverseComparator.java ---------------------------------------------------------------------- diff --git a/jena-base/src/main/java/org/apache/jena/atlas/lib/ReverseComparator.java b/jena-base/src/main/java/org/apache/jena/atlas/lib/ReverseComparator.java new file mode 100644 index 0000000..7019b68 --- /dev/null +++ b/jena-base/src/main/java/org/apache/jena/atlas/lib/ReverseComparator.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.Comparator ; + +/** Comparator that compares the other way round to it's sub-comparator */ +public class ReverseComparator<T> implements Comparator<T> +{ + private final Comparator<T> comparator ; + + public ReverseComparator(Comparator<T> comparator) + { + this.comparator = comparator ; + } + + @Override + public int compare(T o1, T o2) + { + return comparator.compare(o2, o1) ; + } +}
