You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@marmotta.apache.org by ss...@apache.org on 2013/09/06 14:27:07 UTC
[15/18] temporarily added a patched version of javolution with fast
collections, because the released version has several bugs (see
https://java.net/jira/browse/JAVOLUTION-106 and
https://java.net/jira/browse/JAVOLUTION-105)
http://git-wip-us.apache.org/repos/asf/incubator-marmotta/blob/e43574ef/commons/marmotta-commons/src/ext/java/javolution/io/UTF8StreamReader.java
----------------------------------------------------------------------
diff --git a/commons/marmotta-commons/src/ext/java/javolution/io/UTF8StreamReader.java b/commons/marmotta-commons/src/ext/java/javolution/io/UTF8StreamReader.java
new file mode 100644
index 0000000..61fa4fb
--- /dev/null
+++ b/commons/marmotta-commons/src/ext/java/javolution/io/UTF8StreamReader.java
@@ -0,0 +1,316 @@
+/*
+ * Javolution - Java(TM) Solution for Real-Time and Embedded Systems
+ * Copyright (C) 2012 - Javolution (http://javolution.org/)
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software is
+ * freely granted, provided that this notice is preserved.
+ */
+package javolution.io;
+
+import java.io.CharConversionException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Reader;
+
+/**
+ * <p> A UTF-8 stream reader.</p>
+ *
+ * <p> This reader supports surrogate <code>char</code> pairs (representing
+ * characters in the range [U+10000 .. U+10FFFF]). It can also be used
+ * to read characters unicodes (31 bits) directly
+ * (ref. {@link #read()}).</p>
+ *
+ * <p> Each invocation of one of the <code>read()</code> methods may cause one
+ * or more bytes to be read from the underlying byte-input stream.
+ * To enable the efficient conversion of bytes to characters, more bytes may
+ * be read ahead from the underlying stream than are necessary to satisfy
+ * the current read operation.</p>
+ *
+ * <p> Instances of this class can be reused for different input streams
+ * and can be part of a higher level component (e.g. parser) in order
+ * to avoid dynamic buffer allocation when the input source changes.
+ * Also wrapping using a <code>java.io.BufferedReader</code> is unnescessary
+ * as instances of this class embed their own data buffers.</p>
+ *
+ * <p> Note: This reader is unsynchronized and does not test if the UTF-8
+ * encoding is well-formed (e.g. UTF-8 sequences longer than
+ * necessary to encode a character).</p>
+ *
+ * @author <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
+ * @version 2.0, December 9, 2004
+ * @see UTF8StreamWriter
+ */
+public final class UTF8StreamReader extends Reader {
+
+ /**
+ * Holds the current input stream or <code>null</code> if closed.
+ */
+ private InputStream _inputStream;
+
+ /**
+ * Holds the start index.
+ */
+ private int _start;
+
+ /**
+ * Holds the end index.
+ */
+ private int _end;
+
+ /**
+ * Holds the bytes buffer.
+ */
+ private final byte[] _bytes;
+
+ /**
+ * Creates a UTF-8 reader having a byte buffer of moderate capacity (2048).
+ */
+ public UTF8StreamReader() {
+ _bytes = new byte[2048];
+ }
+
+ /**
+ * Creates a UTF-8 reader having a byte buffer of specified capacity.
+ *
+ * @param capacity the capacity of the byte buffer.
+ */
+ public UTF8StreamReader(int capacity) {
+ _bytes = new byte[capacity];
+ }
+
+ /**
+ * Sets the input stream to use for reading until this reader is closed.
+ * For example:[code]
+ * Reader reader = new UTF8StreamReader().setInput(inStream);
+ * [/code] is equivalent but reads twice as fast as [code]
+ * Reader reader = new java.io.InputStreamReader(inStream, "UTF-8");
+ * [/code]
+ *
+ * @param inStream the input stream.
+ * @return this UTF-8 reader.
+ * @throws IllegalStateException if this reader is being reused and
+ * it has not been {@link #close closed} or {@link #reset reset}.
+ */
+ public UTF8StreamReader setInput(InputStream inStream) {
+ if (_inputStream != null)
+ throw new IllegalStateException("Reader not closed or reset");
+ _inputStream = inStream;
+ return this;
+ }
+
+ /**
+ * Indicates if this stream is ready to be read.
+ *
+ * @return <code>true</code> if the next read() is guaranteed not to block
+ * for input; <code>false</code> otherwise.
+ * @throws IOException if an I/O error occurs.
+ */
+ public boolean ready() throws IOException {
+ if (_inputStream == null)
+ throw new IOException("Stream closed");
+ return ((_end - _start) > 0) || (_inputStream.available() != 0);
+ }
+
+ /**
+ * Closes and {@link #reset resets} this reader for reuse.
+ *
+ * @throws IOException if an I/O error occurs.
+ */
+ public void close() throws IOException {
+ if (_inputStream != null) {
+ _inputStream.close();
+ reset();
+ }
+ }
+
+ /**
+ * Reads a single character. This method will block until a character is
+ * available, an I/O error occurs or the end of the stream is reached.
+ *
+ * @return the 31-bits Unicode of the character read, or -1 if the end of
+ * the stream has been reached.
+ * @throws IOException if an I/O error occurs.
+ */
+ public int read() throws IOException {
+ byte b = _bytes[_start];
+ return ((b >= 0) && (_start++ < _end)) ? b : read2();
+ }
+
+ // Reads one full character, blocks if necessary.
+ private int read2() throws IOException {
+ if (_start < _end) {
+ byte b = _bytes[_start++];
+
+ // Decodes UTF-8.
+ if ((b >= 0) && (_moreBytes == 0)) {
+ // 0xxxxxxx
+ return b;
+ } else if (((b & 0xc0) == 0x80) && (_moreBytes != 0)) {
+ // 10xxxxxx (continuation byte)
+ _code = (_code << 6) | (b & 0x3f); // Adds 6 bits to code.
+ if (--_moreBytes == 0) {
+ return _code;
+ } else {
+ return read2();
+ }
+ } else if (((b & 0xe0) == 0xc0) && (_moreBytes == 0)) {
+ // 110xxxxx
+ _code = b & 0x1f;
+ _moreBytes = 1;
+ return read2();
+ } else if (((b & 0xf0) == 0xe0) && (_moreBytes == 0)) {
+ // 1110xxxx
+ _code = b & 0x0f;
+ _moreBytes = 2;
+ return read2();
+ } else if (((b & 0xf8) == 0xf0) && (_moreBytes == 0)) {
+ // 11110xxx
+ _code = b & 0x07;
+ _moreBytes = 3;
+ return read2();
+ } else if (((b & 0xfc) == 0xf8) && (_moreBytes == 0)) {
+ // 111110xx
+ _code = b & 0x03;
+ _moreBytes = 4;
+ return read2();
+ } else if (((b & 0xfe) == 0xfc) && (_moreBytes == 0)) {
+ // 1111110x
+ _code = b & 0x01;
+ _moreBytes = 5;
+ return read2();
+ } else {
+ throw new CharConversionException("Invalid UTF-8 Encoding");
+ }
+ } else { // No more bytes in buffer.
+ if (_inputStream == null)
+ throw new IOException("No input stream or stream closed");
+ _start = 0;
+ _end = _inputStream.read(_bytes, 0, _bytes.length);
+ if (_end > 0) {
+ return read2(); // Continues.
+ } else { // Done.
+ if (_moreBytes == 0) {
+ return -1;
+ } else { // Incomplete sequence.
+ throw new CharConversionException(
+ "Unexpected end of stream");
+ }
+ }
+ }
+ }
+
+ private int _code;
+
+ private int _moreBytes;
+
+ /**
+ * Reads characters into a portion of an array. This method will block
+ * until some input is available, an I/O error occurs or the end of
+ * the stream is reached.
+ *
+ * <p> Note: Characters between U+10000 and U+10FFFF are represented
+ * by surrogate pairs (two <code>char</code>).</p>
+ *
+ * @param cbuf the destination buffer.
+ * @param off the offset at which to start storing characters.
+ * @param len the maximum number of characters to read
+ * @return the number of characters read, or -1 if the end of the
+ * stream has been reached
+ * @throws IOException if an I/O error occurs.
+ */
+ public int read(char cbuf[], int off, int len) throws IOException {
+ if (_inputStream == null)
+ throw new IOException("No input stream or stream closed");
+ if (_start >= _end) { // Fills buffer.
+ _start = 0;
+ _end = _inputStream.read(_bytes, 0, _bytes.length);
+ if (_end <= 0) { // Done.
+ return _end;
+ }
+ }
+ final int off_plus_len = off + len;
+ for (int i = off; i < off_plus_len;) {
+ // assert(_start < _end)
+ byte b = _bytes[_start];
+ if ((b >= 0) && (++_start < _end)) {
+ cbuf[i++] = (char) b; // Most common case.
+ } else if (b < 0) {
+ if (i < off_plus_len - 1) { // Up to two 'char' can be read.
+ int code = read2();
+ if (code < 0x10000) {
+ cbuf[i++] = (char) code;
+ } else if (code <= 0x10ffff) { // Surrogates.
+ cbuf[i++] = (char) (((code - 0x10000) >> 10) + 0xd800);
+ cbuf[i++] = (char) (((code - 0x10000) & 0x3ff) + 0xdc00);
+ } else {
+ throw new CharConversionException("Cannot convert U+"
+ + Integer.toHexString(code)
+ + " to char (code greater than U+10FFFF)");
+ }
+ if (_start < _end) {
+ continue;
+ }
+ }
+ return i - off;
+ } else { // End of buffer (_start >= _end).
+ cbuf[i++] = (char) b;
+ return i - off;
+ }
+ }
+ return len;
+ }
+
+ /**
+ * Reads characters into the specified appendable. This method will block
+ * until the end of the stream is reached.
+ *
+ * @param dest the destination buffer.
+ * @throws IOException if an I/O error occurs.
+ */
+ public void read(Appendable dest) throws IOException {
+ if (_inputStream == null)
+ throw new IOException("No input stream or stream closed");
+ while (true) {
+ if (_start >= _end) { // Fills buffer.
+ _start = 0;
+ _end = _inputStream.read(_bytes, 0, _bytes.length);
+ if (_end <= 0) { // Done.
+ break;
+ }
+ }
+ byte b = _bytes[_start];
+ if (b >= 0) {
+ dest.append((char) b); // Most common case.
+ _start++;
+ } else {
+ int code = read2();
+ if (code < 0x10000) {
+ dest.append((char) code);
+ } else if (code <= 0x10ffff) { // Surrogates.
+ dest.append((char) (((code - 0x10000) >> 10) + 0xd800));
+ dest.append((char) (((code - 0x10000) & 0x3ff) + 0xdc00));
+ } else {
+ throw new CharConversionException("Cannot convert U+"
+ + Integer.toHexString(code)
+ + " to char (code greater than U+10FFFF)");
+ }
+ }
+ }
+ }
+
+ public void reset() {
+ _code = 0;
+ _end = 0;
+ _inputStream = null;
+ _moreBytes = 0;
+ _start = 0;
+ }
+
+ /**
+ * @deprecated Replaced by {@link #setInput(InputStream)}
+ */
+ public UTF8StreamReader setInputStream(InputStream inStream) {
+ return this.setInput(inStream);
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-marmotta/blob/e43574ef/commons/marmotta-commons/src/ext/java/javolution/io/UTF8StreamWriter.java
----------------------------------------------------------------------
diff --git a/commons/marmotta-commons/src/ext/java/javolution/io/UTF8StreamWriter.java b/commons/marmotta-commons/src/ext/java/javolution/io/UTF8StreamWriter.java
new file mode 100644
index 0000000..a5872e3
--- /dev/null
+++ b/commons/marmotta-commons/src/ext/java/javolution/io/UTF8StreamWriter.java
@@ -0,0 +1,338 @@
+/*
+ * Javolution - Java(TM) Solution for Real-Time and Embedded Systems
+ * Copyright (C) 2012 - Javolution (http://javolution.org/)
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software is
+ * freely granted, provided that this notice is preserved.
+ */
+package javolution.io;
+
+import java.io.CharConversionException;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.Writer;
+
+/**
+ * <p> A UTF-8 stream writer.</p>
+ *
+ * <p> This writer supports surrogate <code>char</code> pairs (representing
+ * characters in the range [U+10000 .. U+10FFFF]). It can also be used
+ * to write characters from their unicodes (31 bits) directly
+ * (ref. {@link #write(int)}).</p>
+ *
+ * <p> Instances of this class can be reused for different output streams
+ * and can be part of a higher level component (e.g. serializer) in order
+ * to avoid dynamic buffer allocation when the destination output changes.
+ * Also wrapping using a <code>java.io.BufferedWriter</code> is unnescessary
+ * as instances of this class embed their own data buffers.</p>
+ *
+ * <p> Note: This writer is unsynchronized and always produces well-formed
+ * UTF-8 sequences.</p>
+ *
+ * @author <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
+ * @version 2.0, December 9, 2004
+ */
+public final class UTF8StreamWriter extends Writer {
+
+ /**
+ * Holds the current output stream or <code>null</code> if closed.
+ */
+ private OutputStream _outputStream;
+
+ /**
+ * Holds the bytes' buffer.
+ */
+ private final byte[] _bytes;
+
+ /**
+ * Holds the bytes buffer index.
+ */
+ private int _index;
+
+ /**
+ * Creates a UTF-8 writer having a byte buffer of moderate capacity (2048).
+ */
+ public UTF8StreamWriter() {
+ _bytes = new byte[2048];
+ }
+
+ /**
+ * Creates a UTF-8 writer having a byte buffer of specified capacity.
+ *
+ * @param capacity the capacity of the byte buffer.
+ */
+ public UTF8StreamWriter(int capacity) {
+ _bytes = new byte[capacity];
+ }
+
+ /**
+ * Sets the output stream to use for writing until this writer is closed.
+ * For example:[code]
+ * Writer writer = new UTF8StreamWriter().setOutputStream(out);
+ * [/code] is equivalent but writes faster than [code]
+ * Writer writer = new java.io.OutputStreamWriter(out, "UTF-8");
+ * [/code]
+ *
+ * @param out the output stream.
+ * @return this UTF-8 writer.
+ * @throws IllegalStateException if this writer is being reused and
+ * it has not been {@link #close closed} or {@link #reset reset}.
+ */
+ public UTF8StreamWriter setOutput(OutputStream out) {
+ if (_outputStream != null)
+ throw new IllegalStateException("Writer not closed or reset");
+ _outputStream = out;
+ return this;
+ }
+
+ /**
+ * Writes a single character. This method supports 16-bits
+ * character surrogates.
+ *
+ * @param c <code>char</code> the character to be written (possibly
+ * a surrogate).
+ * @throws IOException if an I/O error occurs.
+ */
+ public void write(char c) throws IOException {
+ if ((c < 0xd800) || (c > 0xdfff)) {
+ write((int) c);
+ } else if (c < 0xdc00) { // High surrogate.
+ _highSurrogate = c;
+ } else { // Low surrogate.
+ int code = ((_highSurrogate - 0xd800) << 10) + (c - 0xdc00)
+ + 0x10000;
+ write(code);
+ }
+ }
+
+ private char _highSurrogate;
+
+ /**
+ * Writes a character given its 31-bits Unicode.
+ *
+ * @param code the 31 bits Unicode of the character to be written.
+ * @throws IOException if an I/O error occurs.
+ */
+ public void write(int code) throws IOException {
+ if ((code & 0xffffff80) == 0) {
+ _bytes[_index] = (byte) code;
+ if (++_index >= _bytes.length) {
+ flushBuffer();
+ }
+ } else { // Writes more than one byte.
+ write2(code);
+ }
+ }
+
+ private void write2(int c) throws IOException {
+ if ((c & 0xfffff800) == 0) { // 2 bytes.
+ _bytes[_index] = (byte) (0xc0 | (c >> 6));
+ if (++_index >= _bytes.length) {
+ flushBuffer();
+ }
+ _bytes[_index] = (byte) (0x80 | (c & 0x3f));
+ if (++_index >= _bytes.length) {
+ flushBuffer();
+ }
+ } else if ((c & 0xffff0000) == 0) { // 3 bytes.
+ _bytes[_index] = (byte) (0xe0 | (c >> 12));
+ if (++_index >= _bytes.length) {
+ flushBuffer();
+ }
+ _bytes[_index] = (byte) (0x80 | ((c >> 6) & 0x3f));
+ if (++_index >= _bytes.length) {
+ flushBuffer();
+ }
+ _bytes[_index] = (byte) (0x80 | (c & 0x3f));
+ if (++_index >= _bytes.length) {
+ flushBuffer();
+ }
+ } else if ((c & 0xff200000) == 0) { // 4 bytes.
+ _bytes[_index] = (byte) (0xf0 | (c >> 18));
+ if (++_index >= _bytes.length) {
+ flushBuffer();
+ }
+ _bytes[_index] = (byte) (0x80 | ((c >> 12) & 0x3f));
+ if (++_index >= _bytes.length) {
+ flushBuffer();
+ }
+ _bytes[_index] = (byte) (0x80 | ((c >> 6) & 0x3f));
+ if (++_index >= _bytes.length) {
+ flushBuffer();
+ }
+ _bytes[_index] = (byte) (0x80 | (c & 0x3f));
+ if (++_index >= _bytes.length) {
+ flushBuffer();
+ }
+ } else if ((c & 0xf4000000) == 0) { // 5 bytes.
+ _bytes[_index] = (byte) (0xf8 | (c >> 24));
+ if (++_index >= _bytes.length) {
+ flushBuffer();
+ }
+ _bytes[_index] = (byte) (0x80 | ((c >> 18) & 0x3f));
+ if (++_index >= _bytes.length) {
+ flushBuffer();
+ }
+ _bytes[_index] = (byte) (0x80 | ((c >> 12) & 0x3f));
+ if (++_index >= _bytes.length) {
+ flushBuffer();
+ }
+ _bytes[_index] = (byte) (0x80 | ((c >> 6) & 0x3f));
+ if (++_index >= _bytes.length) {
+ flushBuffer();
+ }
+ _bytes[_index] = (byte) (0x80 | (c & 0x3f));
+ if (++_index >= _bytes.length) {
+ flushBuffer();
+ }
+ } else if ((c & 0x80000000) == 0) { // 6 bytes.
+ _bytes[_index] = (byte) (0xfc | (c >> 30));
+ if (++_index >= _bytes.length) {
+ flushBuffer();
+ }
+ _bytes[_index] = (byte) (0x80 | ((c >> 24) & 0x3f));
+ if (++_index >= _bytes.length) {
+ flushBuffer();
+ }
+ _bytes[_index] = (byte) (0x80 | ((c >> 18) & 0x3f));
+ if (++_index >= _bytes.length) {
+ flushBuffer();
+ }
+ _bytes[_index] = (byte) (0x80 | ((c >> 12) & 0x3F));
+ if (++_index >= _bytes.length) {
+ flushBuffer();
+ }
+ _bytes[_index] = (byte) (0x80 | ((c >> 6) & 0x3F));
+ if (++_index >= _bytes.length) {
+ flushBuffer();
+ }
+ _bytes[_index] = (byte) (0x80 | (c & 0x3F));
+ if (++_index >= _bytes.length) {
+ flushBuffer();
+ }
+ } else {
+ throw new CharConversionException("Illegal character U+"
+ + Integer.toHexString(c));
+ }
+ }
+
+ /**
+ * Writes a portion of an array of characters.
+ *
+ * @param cbuf the array of characters.
+ * @param off the offset from which to start writing characters.
+ * @param len the number of characters to write.
+ * @throws IOException if an I/O error occurs.
+ */
+ public void write(char cbuf[], int off, int len) throws IOException {
+ final int off_plus_len = off + len;
+ for (int i = off; i < off_plus_len;) {
+ char c = cbuf[i++];
+ if (c < 0x80) {
+ _bytes[_index] = (byte) c;
+ if (++_index >= _bytes.length) {
+ flushBuffer();
+ }
+ } else {
+ write(c);
+ }
+ }
+ }
+
+ /**
+ * Writes a portion of a string.
+ *
+ * @param str a String.
+ * @param off the offset from which to start writing characters.
+ * @param len the number of characters to write.
+ * @throws IOException if an I/O error occurs
+ */
+ public void write(String str, int off, int len) throws IOException {
+ final int off_plus_len = off + len;
+ for (int i = off; i < off_plus_len;) {
+ char c = str.charAt(i++);
+ if (c < 0x80) {
+ _bytes[_index] = (byte) c;
+ if (++_index >= _bytes.length) {
+ flushBuffer();
+ }
+ } else {
+ write(c);
+ }
+ }
+ }
+
+ /**
+ * Writes the specified character sequence.
+ *
+ * @param csq the character sequence.
+ * @throws IOException if an I/O error occurs
+ */
+ public void write(CharSequence csq) throws IOException {
+ final int length = csq.length();
+ for (int i = 0; i < length;) {
+ char c = csq.charAt(i++);
+ if (c < 0x80) {
+ _bytes[_index] = (byte) c;
+ if (++_index >= _bytes.length) {
+ flushBuffer();
+ }
+ } else {
+ write(c);
+ }
+ }
+ }
+
+ /**
+ * Flushes the stream. If the stream has saved any characters from the
+ * various write() methods in a buffer, write them immediately to their
+ * intended destination. Then, if that destination is another character or
+ * byte stream, flush it. Thus one flush() invocation will flush all the
+ * buffers in a chain of Writers and OutputStreams.
+ *
+ * @throws IOException if an I/O error occurs.
+ */
+ public void flush() throws IOException {
+ flushBuffer();
+ _outputStream.flush();
+ }
+
+ /**
+ * Closes and {@link #reset resets} this writer for reuse.
+ *
+ * @throws IOException if an I/O error occurs
+ */
+ public void close() throws IOException {
+ if (_outputStream != null) {
+ flushBuffer();
+ _outputStream.close();
+ reset();
+ }
+ }
+
+ /**
+ * Flushes the internal bytes buffer.
+ *
+ * @throws IOException if an I/O error occurs
+ */
+ private void flushBuffer() throws IOException {
+ if (_outputStream == null)
+ throw new IOException("Stream closed");
+ _outputStream.write(_bytes, 0, _index);
+ _index = 0;
+ }
+
+ public void reset() {
+ _highSurrogate = 0;
+ _index = 0;
+ _outputStream = null;
+ }
+
+ /**
+ * @deprecated Replaced by {@link #setOutput(OutputStream)}
+ */
+ public UTF8StreamWriter setOutputStream(OutputStream out) {
+ return this.setOutput(out);
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-marmotta/blob/e43574ef/commons/marmotta-commons/src/ext/java/javolution/io/Union.java
----------------------------------------------------------------------
diff --git a/commons/marmotta-commons/src/ext/java/javolution/io/Union.java b/commons/marmotta-commons/src/ext/java/javolution/io/Union.java
new file mode 100644
index 0000000..e8ae270
--- /dev/null
+++ b/commons/marmotta-commons/src/ext/java/javolution/io/Union.java
@@ -0,0 +1,54 @@
+/*
+ * Javolution - Java(TM) Solution for Real-Time and Embedded Systems
+ * Copyright (C) 2012 - Javolution (http://javolution.org/)
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software is
+ * freely granted, provided that this notice is preserved.
+ */
+package javolution.io;
+
+/**
+ * <p> Equivalent to <code>C/C++ union</code>; this class works in the same
+ * way as {@link Struct} (sub-class) except that all members are mapped
+ * to the same location in memory.</p>
+ * <p> Here is an example of C union:
+ * [code]
+ * union Number {
+ * int asInt;
+ * float asFloat;
+ * char asString[12];
+ * };[/code]</p>
+ * <p> And its Java equivalent:
+ * [code]
+ * public class Number extends Union {
+ * Signed32 asInt = new Signed32();
+ * Float32 asFloat = new Float32();
+ * Utf8String asString = new Utf8String(12);
+ * }[/code]</p>
+ * <p> As for any {@link Struct}, fields are directly accessible:
+ * [code]
+ * Number num = new Number();
+ * num.asInt.set(23);
+ * num.asString.set("23"); // Null terminated (C compatible)
+ * float f = num.asFloat.get();[/code]</p>
+ *
+ * @author <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
+ * @version 1.0, October 4, 2004
+ */
+public abstract class Union extends Struct {
+
+ /**
+ * Default constructor.
+ */
+ public Union() {}
+
+ /**
+ * Returns <code>true</code>.
+ *
+ * @return <code>true</code>
+ */
+ public final boolean isUnion() {
+ return true;
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-marmotta/blob/e43574ef/commons/marmotta-commons/src/ext/java/javolution/io/package-info.java
----------------------------------------------------------------------
diff --git a/commons/marmotta-commons/src/ext/java/javolution/io/package-info.java b/commons/marmotta-commons/src/ext/java/javolution/io/package-info.java
new file mode 100644
index 0000000..6e000ae
--- /dev/null
+++ b/commons/marmotta-commons/src/ext/java/javolution/io/package-info.java
@@ -0,0 +1,7 @@
+/**
+<p> Utility classes for input and output such as
+ {@link javolution.io.Struct Struct} and {@link javolution.io.Union Union}
+ for direct interoperability with C/C++.</p>
+ */
+package javolution.io;
+
http://git-wip-us.apache.org/repos/asf/incubator-marmotta/blob/e43574ef/commons/marmotta-commons/src/ext/java/javolution/lang/Configurable.java
----------------------------------------------------------------------
diff --git a/commons/marmotta-commons/src/ext/java/javolution/lang/Configurable.java b/commons/marmotta-commons/src/ext/java/javolution/lang/Configurable.java
new file mode 100644
index 0000000..394c60e
--- /dev/null
+++ b/commons/marmotta-commons/src/ext/java/javolution/lang/Configurable.java
@@ -0,0 +1,283 @@
+/*
+ * Javolution - Java(TM) Solution for Real-Time and Embedded Systems
+ * Copyright (C) 2012 - Javolution (http://javolution.org/)
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software is
+ * freely granted, provided that this notice is preserved.
+ */
+package javolution.lang;
+
+import java.lang.reflect.Field;
+
+import javolution.context.LogContext;
+import javolution.context.SecurityContext;
+import javolution.context.SecurityContext.Permission;
+import javolution.osgi.internal.OSGiServices;
+import javolution.text.DefaultTextFormat;
+import javolution.text.TextContext;
+
+/**
+ * <p> An element which is configurable without presupposing how the
+ * configuration is done.</p>
+ *
+ * <p> Does your class need to know or has to assume that the configuration is
+ * coming from system properties ??</p>
+ *
+ * <p> The response is obviously NO !</p>
+ *
+ * <p> Let's compare the following examples:
+ * [code]
+ * class Document {
+ * private static final Font FONT
+ * = Font.decode(System.getProperty("pkg.Document#FONT") != null ?
+ * System.getProperty("FONT") : "Arial-BOLD-18");
+ * }[/code]</p>
+ *
+ * <p>With the following:
+ * [code]
+ * class Document {
+ * public static final Configurable<Font> FONT = new Configurable<Font>() {
+ * @Override
+ * protected Font getDefault() {
+ * new Font("Arial", Font.BOLD, 18);
+ * }
+ * };
+ * }[/code]</p>
+ *
+ * <p> Not only the second example is cleaner, but the actual configuration
+ * data can come from anywhere, from system properties (default),
+ * OSGi Configuration Admin service, another bundle, etc.
+ * Low level code does not need to know.</p>
+ *
+ * <p> Configurables may perform any logic upon initialization or
+ * update. Users are notified of configuration events through
+ * the OSGi {@link Configurable.Listener} service.
+ * [code]
+ * class Index {
+ * // Holds the number of unique preallocated instances (default {@code 1024}).
+ * public static final Configurable<Integer> UNIQUE = new Configurable<Integer>() {
+ * @Override
+ * protected Integer getDefault() {
+ * return 1024;
+ * }
+ * @Override
+ * protected Integer initialized(Integer value) {
+ * return MathLib.min(value, 65536); // Hard-limiting
+ * }
+ * @Override
+ * protected Integer reconfigured(Integer oldCount, Integer newCount) {
+ * throw new UnsupportedOperationException("Unicity reconfiguration not supported.");
+ * }
+ * }
+ * }[/code]</p>
+ *
+ * @author <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
+ * @version 6.0, July 21, 2013
+ */
+public abstract class Configurable<T> {
+
+ /**
+ * Services to be published by any one interested in being informed of
+ * configurable changes.
+ */
+ public interface Listener {
+
+ /**
+ * Receives notification that a configurable has been initialized..
+ *
+ * @param configurable the configurable instance being initialized.
+ * @param value the initial value.
+ */
+ <T> void configurableInitialized(Configurable<T> configurable, T value);
+
+ /**
+ * Receives notification that a configurable has been updated.
+ *
+ * @param configurable the configurable instance being updated.
+ * @param oldValue the previous value.
+ * @param newValue the updated value.
+ */
+ <T> void configurableReconfigured(Configurable<T> configurable,
+ T oldValue, T newValue);
+
+ }
+
+ /**
+ * Holds the general permission to reconfigure configurable instances
+ * (action <code>"reconfigure"</code>).
+ * Whether or not that permission is granted depends on the current
+ * {@link SecurityContext}. It is possible that the general permission
+ * to reconfigure a configurable is granted but revoked for a specific
+ * instance. Also, the general permission to reconfigure a configurable
+ * may be revoked but granted only for a specific instance.
+ */
+ public static Permission<Configurable<?>> RECONFIGURE_PERMISSION = new Permission<Configurable<?>>(
+ Configurable.class, "reconfigure");
+
+ /**
+ * Holds the configurable name.
+ */
+ private String name;
+
+ /**
+ * Holds the reconfigure permission.
+ */
+ private final Permission<Configurable<T>> reconfigurePermission;
+
+ /**
+ * Holds the configurable value.
+ */
+ private volatile T value;
+
+ /**
+ * Creates a new configurable. If a system property exist for this
+ * configurable's {@link #getName() name}, then
+ * the {@link #parse parsed} value of the property supersedes the
+ * {@link #getDefault() default} value of this configurable.
+ * For example, running the JVM with
+ * the option {@code -Djavolution.context.ConcurrentContext#CONCURRENCY=0}
+ * disables concurrency support.
+ */
+ public Configurable() {
+ reconfigurePermission = new Permission<Configurable<T>>(
+ Configurable.class, "reconfigure", this);
+ String name = getName();
+ T defaultValue = getDefault();
+ if (name != null) {
+ try { // Checks system properties.
+ String property = System.getProperty(name);
+ if (property != null) {
+ defaultValue = parse(property); // Supersedes.
+ LogContext.debug(name, ", System Properties Value: ",
+ defaultValue);
+ }
+ } catch (SecurityException securityError) {
+ // Ok, current runtime does not allow system properties access.
+ }
+ }
+ this.name = name;
+ this.value = initialized(defaultValue);
+ Object[] listeners = OSGiServices.getConfigurableListeners();
+ for (Object listener : listeners) {
+ ((Listener) listener).configurableInitialized(this, this.value);
+ }
+ }
+
+ /**
+ * Returns this configurable value.
+ */
+ public T get() {
+ return value;
+ }
+
+ /**
+ * Returns this configurable name. By convention, the name of the
+ * configurable is the name of the static field holding the
+ * configurable (e.g. "javolution.context.ConcurrentContext#CONCURRENCY").
+ * This method should be overridden if the enclosing class needs to be
+ * impervious to obfuscation or if the enclosing class defines multiple
+ * configurable fields.
+ *
+ * @throws UnsupportedOperationException if the enclosing class has
+ * multiple configurable static fields.
+ */
+ public String getName() {
+ if (name != null)
+ return name; // Already set.
+ Class<?> thisClass = this.getClass();
+ Class<?> enclosingClass = thisClass.getEnclosingClass();
+ String fieldName = null;
+ for (Field field : enclosingClass.getFields()) {
+ if (field.getType().isAssignableFrom(thisClass)) {
+ if (fieldName != null) // Indistinguishable field types.
+ throw new UnsupportedOperationException(
+ "Multiple configurables static fields in the same class" +
+ "requires the Configurable.getName() method to be overriden.");
+ fieldName = field.getName();
+ }
+ }
+ return (fieldName != null) ? enclosingClass.getName() + "#" + fieldName
+ : null;
+ }
+
+ /**
+ * Returns the permission to configure this instance.
+ */
+ public Permission<Configurable<T>> getReconfigurePermission() {
+ return reconfigurePermission;
+ }
+
+ /**
+ * Reconfigures this instance with the specified value if authorized
+ * by the {@link SecurityContext}. This method returns the actual new
+ * value which may be different from the requested new value
+ * (see {@link #reconfigured(Object, Object)}).
+ *
+ * @param newValue the requested new value.
+ * @return the actual new value.
+ * @throws SecurityException if the permission to reconfigure this
+ * configurable is not granted.
+ * @throws UnsupportedOperationException if this configurable does not
+ * support dynamic reconfiguration.
+ */
+ public T reconfigure(T newValue) {
+ SecurityContext.check(reconfigurePermission);
+ synchronized (this) {
+ T oldValue = this.value;
+ this.value = reconfigured(oldValue, newValue);
+ Object[] listeners = OSGiServices.getConfigurableListeners();
+ for (Object listener : listeners) {
+ ((Listener) listener).configurableReconfigured(this, oldValue,
+ this.value);
+ }
+ return this.value;
+ }
+ }
+
+ /**
+ * Returns this configurable default value (always different from
+ * {@code null}).
+ */
+ protected abstract T getDefault();
+
+ /**
+ * This methods is called when the configurable is initialized.
+ * Developers may override this method to perform
+ * any initialization logic (e.g. input validation).
+ *
+ * @param value the requested value for this configurable.
+ * @return the actual value of this configurable.
+ */
+ protected T initialized(T value) {
+ return value;
+ }
+
+ /**
+ * Parses the specified text to return the corresponding value.
+ * This method is used to initialize this configurable from
+ * system properties. The default implementation uses the
+ * {@link TextContext} to retrieve the text format
+ * (based on the {@link DefaultTextFormat} class annotation).
+ */
+ @SuppressWarnings("unchecked")
+ protected T parse(String str) {
+ Class<? extends T> type = (Class<? extends T>) getDefault().getClass();
+ return TextContext.getFormat(type).parse(str);
+ }
+
+ /**
+ * This methods is called when the configurable is reconfigured.
+ * Developers may override this method to perform
+ * any reconfiguration logic (e.g. hard limiting values).
+ *
+ * @param oldValue the old value.
+ * @param newValue the requested new value.
+ * @return the actual new value of this configurable.
+ * @throws UnsupportedOperationException if this configurable does not
+ * support dynamic reconfiguration.
+ */
+ protected T reconfigured(T oldValue, T newValue) {
+ return newValue;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-marmotta/blob/e43574ef/commons/marmotta-commons/src/ext/java/javolution/lang/Immutable.java
----------------------------------------------------------------------
diff --git a/commons/marmotta-commons/src/ext/java/javolution/lang/Immutable.java b/commons/marmotta-commons/src/ext/java/javolution/lang/Immutable.java
new file mode 100644
index 0000000..9b60984
--- /dev/null
+++ b/commons/marmotta-commons/src/ext/java/javolution/lang/Immutable.java
@@ -0,0 +1,45 @@
+/*
+ * Javolution - Java(TM) Solution for Real-Time and Embedded Systems
+ * Copyright (C) 2012 - Javolution (http://javolution.org/)
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software is
+ * freely granted, provided that this notice is preserved.
+ */
+package javolution.lang;
+
+/**
+ * <p> An object capable of returning a {@link #value value} not subject or
+ * susceptible of change or variation. For example, {@code Immutable<List>}
+ * has a {@code List} value which is guaranteed to be constant (not modifiable
+ * by anybody). Classes implementing this interface do not need themselves to
+ * be unmodifiable. If the value and the class are the same, the
+ * {@link ValueType} sub-interface can be implemented.
+ * [code]
+ * class Polygon extends Shape implements ValueType<Shape> { // extends Immutable<Shape>
+ * private List<Point2D> vertices;
+ * public Polygon(Immutable<List<Point2D>> vertices) { // Immutable<List> has a constant List value.
+ * this.vertices = vertices.value(); // No defensive copying required (vertices.value() is certified constant).
+ * }
+ * public Polygon value() { return this; } // As per ValueType contract.
+ * }[/code]</p>
+ * <p> {@link javolution.util.FastCollection FastCollection/FastMap} have
+ * direct support for immutable.
+ * [code]
+ * Polygon triangle = new Polygon(new FastTable<Point2D>().addAll(p1, p2, p3).toImmutable());[/code]</p>
+ *
+ * @author <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
+ * @version 6.0, July 21, 2013
+ * @param <T> The type of the immutable constant value.
+ * @see <a href="http://en.wikipedia.org/wiki/Immutable_object">
+ * Wikipedia: Immutable Object<a>
+ * @see javolution.util.FastCollection#toImmutable
+ */
+public interface Immutable<T> {
+
+ /**
+ * Returns the constant value held by this object.
+ */
+ T value();
+
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-marmotta/blob/e43574ef/commons/marmotta-commons/src/ext/java/javolution/lang/Initializer.java
----------------------------------------------------------------------
diff --git a/commons/marmotta-commons/src/ext/java/javolution/lang/Initializer.java b/commons/marmotta-commons/src/ext/java/javolution/lang/Initializer.java
new file mode 100644
index 0000000..81f2823
--- /dev/null
+++ b/commons/marmotta-commons/src/ext/java/javolution/lang/Initializer.java
@@ -0,0 +1,149 @@
+/*
+ * Javolution - Java(TM) Solution for Real-Time and Embedded Systems
+ * Copyright (C) 2012 - Javolution (http://javolution.org/)
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software is
+ * freely granted, provided that this notice is preserved.
+ */
+package javolution.lang;
+
+import java.util.Vector;
+import javolution.context.LogContext;
+
+/**
+ * <p> An initializer for all classes loaded by any given class loader.</p>
+ *
+ * <p> Initialization of classes at startup (or during bundle activation)
+ * ensures a significantly improved worst case execution time especially
+ * if the classes has {@link Configurable configuration logic} to be
+ * executed then.</p>
+ *
+ * <p> Javolution activator initialize {@link Realtime} classes when started.
+ * When running outside OSGi the method
+ * {@code javolution.osgi.internal.OSGiServices.initializeRealtimeClasses()}
+ * can be used to that effect..</p>
+ *
+ * <p> Class loading can be performed in a lazy manner and therefore some parts
+ * of the class loading process may be done on first use rather than at
+ * load time. Javolution bundle activator ensure that <b>all</b> its classes
+ * are initialized at start up.
+ * The following code illustrates how this can be done for any bundle.
+ * [code]
+ * public class MyActivator implements BundleActivator {
+ * public void start(BundleContext bc) throws Exception {
+ * Initializer initializer = new Initializer(MyActivator.class.getClassLoader());
+ * initializer.loadClass(com.foo.internal.UnreferencedClass.class);
+ * // Load explicitly classes not directly or indirectly referenced.
+ * ...
+ * initializer.initializeLoadedClasses(); // Recursive loading/initialization.
+ * ... // Continue activation
+ * }
+ * }[/code]</p>
+ *
+ * <p> This utility use reflection to find the classes loaded and may not be
+ * supported on all platforms.</p>
+ *
+ * @author <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
+ * @version 5.1, July 26, 2007
+ */
+public class Initializer {
+
+ /**
+ * Indicates if the class being initialized should be logged
+ * (default {@code false}).
+ */
+ public static final Configurable<Boolean> SHOW_INITIALIZED = new Configurable<Boolean>() {
+ @Override
+ protected Boolean getDefault() {
+ return false;
+ }
+ };
+
+ /** The class loader for this initializer */
+ private final ClassLoader classLoader;
+
+ /**
+ * Creates an initializer for the specified class loader.
+ */
+ public Initializer(ClassLoader classLoader) {
+ this.classLoader = classLoader;
+ }
+
+ /**
+ * Returns the classes loaded by the class loader of this initializer or
+ * <code>null</code> if not supported by the platform.
+ */
+ @SuppressWarnings("unchecked")
+ public Class<?>[] loadedClasses() {
+ Class<?> cls = classLoader.getClass();
+ while (cls != java.lang.ClassLoader.class) {
+ cls = cls.getSuperclass();
+ }
+ try {
+ java.lang.reflect.Field fldClasses = cls
+ .getDeclaredField("classes");
+ fldClasses.setAccessible(true);
+ Vector<Class<?>> list = (Vector<Class<?>>) fldClasses
+ .get(classLoader);
+ Class<?>[] classes = new Class<?>[list.size()];
+ for (int i = 0; i < classes.length; i++) {
+ classes[i] = list.get(i);
+ }
+ return classes;
+ } catch (Throwable e) {
+ return null;
+ }
+ }
+
+ /**
+ * Loads the specified class (does not perform any initialization).
+ * This method is typically used to load unreferenced classes.
+ */
+ public void loadClass(Class<?> cls) {
+ try {
+ classLoader.loadClass(cls.getName());
+ } catch (ClassNotFoundException e) {
+ LogContext.debug("Class " + cls + " not found.");
+ }
+ }
+
+ /**
+ * Initializes all the loaded classes. If the initialization leads to more
+ * classes being loaded, these classes are initialized as well
+ * (recursive process).
+ *
+ * @return {@code true} if initialization has been performed successfully;
+ * {@code false} otherwise.
+ */
+ public boolean initializeLoadedClasses() {
+ boolean isInitializationSuccessful = true;
+ int nbrClassesInitialized = 0;
+ while (true) {
+ Class<?>[] classes = loadedClasses();
+ if (classes == null) {
+ LogContext
+ .debug("Automatic class initialization not supported.");
+ return false;
+ }
+ if (nbrClassesInitialized >= classes.length)
+ break; // Done.
+ for (int i = nbrClassesInitialized; i < classes.length; i++) {
+ Class<?> cls = classes[i];
+ try {
+ if (SHOW_INITIALIZED.get())
+ LogContext.debug("Initialize ", cls.getName());
+ Class.forName(cls.getName(), true, classLoader);
+ } catch (ClassNotFoundException ex) {
+ isInitializationSuccessful = false;
+ LogContext.error(ex); // Should never happen.
+ }
+ }
+ nbrClassesInitialized = classes.length;
+ }
+ LogContext.debug("Initialization of ", nbrClassesInitialized,
+ " classes loaded by ", classLoader);
+ return isInitializationSuccessful;
+ }
+
+}
\ No newline at end of file