consumer) {
+ this.consumer = consumer;
+ return this;
+ }
+}
diff --git a/fine-jodd/src/main/java/com/fr/third/jodd/JoddModule.java b/fine-jodd/src/main/java/com/fr/third/jodd/cli/package-info.java
similarity index 88%
rename from fine-jodd/src/main/java/com/fr/third/jodd/JoddModule.java
rename to fine-jodd/src/main/java/com/fr/third/jodd/cli/package-info.java
index be9c5ff42..10b3577d7 100644
--- a/fine-jodd/src/main/java/com/fr/third/jodd/JoddModule.java
+++ b/fine-jodd/src/main/java/com/fr/third/jodd/cli/package-info.java
@@ -23,16 +23,7 @@
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
-package com.fr.third.jodd;
-
/**
- * Optional interface for Jodd modules.
+ * Small parser for command line arguments.
*/
-public interface JoddModule {
-
- /**
- * Invoked once when module has been created.
- */
- public void start();
-
-}
\ No newline at end of file
+package com.fr.third.jodd.cli;
\ No newline at end of file
diff --git a/fine-jodd/src/main/java/com/fr/third/jodd/core/JoddCore.java b/fine-jodd/src/main/java/com/fr/third/jodd/core/JoddCore.java
index b6f22b934..31c686b0e 100644
--- a/fine-jodd/src/main/java/com/fr/third/jodd/core/JoddCore.java
+++ b/fine-jodd/src/main/java/com/fr/third/jodd/core/JoddCore.java
@@ -26,53 +26,40 @@
package com.fr.third.jodd.core;
import com.fr.third.jodd.util.StringPool;
-import com.fr.third.jodd.util.cl.ClassLoaderStrategy;
-import com.fr.third.jodd.util.cl.DefaultClassLoaderStrategy;
-import com.fr.third.jodd.Jodd;
-import com.fr.third.jodd.io.FileUtilParams;
-import com.fr.third.jodd.util.StringPool;
-import com.fr.third.jodd.util.cl.ClassLoaderStrategy;
-import com.fr.third.jodd.util.cl.DefaultClassLoaderStrategy;
+
+import java.security.Security;
/**
- * Jodd CORE module.
- * Contains some global defaults.
+ * Jodd library-wide properties.
*/
public class JoddCore {
+ static {
+ // Starting from Java8 u151, the `Unlimited Strength Jurisdiction Policy Files`
+ // are included with Java, but has to be enabled.
+ // They are enabled on Java9 by default.
+ Security.setProperty("crypto.policy", "unlimited");
+ }
+
+ // ---------------------------------------------------------------- settings
+
/**
- * Default temp file prefix.
+ * Default prefix for temporary files.
*/
public static String tempFilePrefix = "jodd-";
/**
- * Default file encoding (UTF8).
+ * The encoding used across the Jodd classes, "UTF-8" by default.
*/
public static String encoding = StringPool.UTF_8;
/**
- * Default IO buffer size (16 KB).
+ * Buffer size for various I/O operations.
*/
public static int ioBufferSize = 16384;
-
- /**
- * Default parameters used in {@link com.fr.third.jodd.io.FileUtil} operations.
- */
- public static FileUtilParams fileUtilParams = new FileUtilParams();
-
/**
- * Default class loader strategy.
+ * Flag that controls the {@code Unsafe} usage (if system detects it). Enabled by default.
*/
- public static ClassLoaderStrategy classLoaderStrategy = new DefaultClassLoaderStrategy();
-
- // ---------------------------------------------------------------- module
-
- static {
- init();
- }
-
- public static void init() {
- Jodd.init(JoddCore.class);
- }
+ public static boolean unsafeUsageEnabled = true;
}
\ No newline at end of file
diff --git a/fine-jodd/src/main/java/com/fr/third/jodd/datetime/DateTimeStamp.java b/fine-jodd/src/main/java/com/fr/third/jodd/datetime/DateTimeStamp.java
index 4951fd69f..4eee7950d 100644
--- a/fine-jodd/src/main/java/com/fr/third/jodd/datetime/DateTimeStamp.java
+++ b/fine-jodd/src/main/java/com/fr/third/jodd/datetime/DateTimeStamp.java
@@ -37,7 +37,9 @@ import java.io.Serializable;
*
* @see JDateTime
* @see JulianDateStamp
+ * @deprecated jodd目前版本为5.1.6, 此版本已移除此类, 兼容问题暂不删除此类
*/
+@Deprecated
public class DateTimeStamp implements Comparable, Serializable, Cloneable {
/**
diff --git a/fine-jodd/src/main/java/com/fr/third/jodd/datetime/JDateTime.java b/fine-jodd/src/main/java/com/fr/third/jodd/datetime/JDateTime.java
index 98d312996..553e09068 100644
--- a/fine-jodd/src/main/java/com/fr/third/jodd/datetime/JDateTime.java
+++ b/fine-jodd/src/main/java/com/fr/third/jodd/datetime/JDateTime.java
@@ -128,7 +128,9 @@ import static com.fr.third.jodd.util.HashCode.hash;
*
*
* More info: Julian Date on Wikipedia
+ * @deprecated jodd目前版本为5.1.6, 此版本已移除此类, 兼容问题暂不删除此类
*/
+@Deprecated
public class JDateTime implements Comparable, Cloneable, Serializable {
public static final String DEFAULT_FORMAT = "YYYY-MM-DD hh:mm:ss.mss";
diff --git a/fine-jodd/src/main/java/com/fr/third/jodd/datetime/JDateTimeDefault.java b/fine-jodd/src/main/java/com/fr/third/jodd/datetime/JDateTimeDefault.java
index 4a8429f13..e9646f16c 100644
--- a/fine-jodd/src/main/java/com/fr/third/jodd/datetime/JDateTimeDefault.java
+++ b/fine-jodd/src/main/java/com/fr/third/jodd/datetime/JDateTimeDefault.java
@@ -25,8 +25,6 @@
package com.fr.third.jodd.datetime;
-import com.fr.third.jodd.datetime.format.Iso8601JdtFormatter;
-import com.fr.third.jodd.datetime.format.JdtFormatter;
import com.fr.third.jodd.datetime.format.Iso8601JdtFormatter;
import com.fr.third.jodd.datetime.format.JdtFormatter;
@@ -35,7 +33,9 @@ import java.util.Locale;
/**
* Defaults for {@link JDateTime}.
+ * @deprecated jodd目前版本为5.1.6, 此版本已移除此类, 兼容问题暂不删除此类
*/
+@Deprecated
@SuppressWarnings({"RedundantFieldInitialization"})
public class JDateTimeDefault {
diff --git a/fine-jodd/src/main/java/com/fr/third/jodd/datetime/JStopWatch.java b/fine-jodd/src/main/java/com/fr/third/jodd/datetime/JStopWatch.java
index 56c4bf77d..daf047fb9 100644
--- a/fine-jodd/src/main/java/com/fr/third/jodd/datetime/JStopWatch.java
+++ b/fine-jodd/src/main/java/com/fr/third/jodd/datetime/JStopWatch.java
@@ -31,7 +31,10 @@ import java.util.ArrayList;
/**
* Nice thread-aware stopwatch that supports time spans, cumulative times and laps.
* Useful for all kind of profiling, time measurements etc.
+ *
+ * @deprecated jodd目前版本为5.1.6, 此版本已移除此类, 兼容问题暂不删除此类
*/
+@Deprecated
public class JStopWatch {
/**
diff --git a/fine-jodd/src/main/java/com/fr/third/jodd/datetime/JulianDateStamp.java b/fine-jodd/src/main/java/com/fr/third/jodd/datetime/JulianDateStamp.java
index b24c9da0d..e42977955 100644
--- a/fine-jodd/src/main/java/com/fr/third/jodd/datetime/JulianDateStamp.java
+++ b/fine-jodd/src/main/java/com/fr/third/jodd/datetime/JulianDateStamp.java
@@ -62,7 +62,9 @@ import java.io.Serializable;
* @see TimeUtil
* @see JDateTime
* @see DateTimeStamp
+ * @deprecated jodd目前版本为5.1.6, 此版本已移除此类, 兼容问题暂不删除此类
*/
+@Deprecated
public class JulianDateStamp implements Serializable, Cloneable {
/**
diff --git a/fine-jodd/src/main/java/com/fr/third/jodd/datetime/Period.java b/fine-jodd/src/main/java/com/fr/third/jodd/datetime/Period.java
index b03c9a950..441a3c612 100644
--- a/fine-jodd/src/main/java/com/fr/third/jodd/datetime/Period.java
+++ b/fine-jodd/src/main/java/com/fr/third/jodd/datetime/Period.java
@@ -30,7 +30,10 @@ package com.fr.third.jodd.datetime;
* easy to calculate period in days - just by subtracting two julian day numbers.
* However, calculating hours, minutes and seconds would require more calculation
* and this class provides simple and faster period calculation.
+ *
+ * @deprecated jodd目前版本为5.1.6, 此版本已移除此类, 兼容问题暂不删除此类
*/
+@Deprecated
public class Period {
protected final long days;
diff --git a/fine-jodd/src/main/java/com/fr/third/jodd/datetime/TimeUtil.java b/fine-jodd/src/main/java/com/fr/third/jodd/datetime/TimeUtil.java
index 2360af7fb..8b13291dc 100644
--- a/fine-jodd/src/main/java/com/fr/third/jodd/datetime/TimeUtil.java
+++ b/fine-jodd/src/main/java/com/fr/third/jodd/datetime/TimeUtil.java
@@ -35,7 +35,10 @@ import java.util.Locale;
* {@link JDateTime} and it contains few utilities that may be used
* elsewhere, although {@link JDateTime} is recommended for all time
* manipulation.
+ *
+ * @deprecated jodd目前版本为5.1.6, 此版本已移除此类, 兼容问题暂不删除此类
*/
+@Deprecated
public class TimeUtil {
public static final int SECONDS_IN_DAY = 60 * 60 * 24;
diff --git a/fine-jodd/src/main/java/com/fr/third/jodd/datetime/TimeZoneUtil.java b/fine-jodd/src/main/java/com/fr/third/jodd/datetime/TimeZoneUtil.java
index 3eedfea39..d8ce150ae 100644
--- a/fine-jodd/src/main/java/com/fr/third/jodd/datetime/TimeZoneUtil.java
+++ b/fine-jodd/src/main/java/com/fr/third/jodd/datetime/TimeZoneUtil.java
@@ -29,7 +29,10 @@ import java.util.TimeZone;
/**
* Misc timezone utilities.
+ *
+ * @deprecated jodd目前版本为5.1.6, 此版本已移除此类, 兼容问题暂不删除此类
*/
+@Deprecated
public class TimeZoneUtil {
/**
diff --git a/fine-jodd/src/main/java/com/fr/third/jodd/datetime/format/AbstractFormatter.java b/fine-jodd/src/main/java/com/fr/third/jodd/datetime/format/AbstractFormatter.java
index 1c4bbffb5..aec8a7f09 100644
--- a/fine-jodd/src/main/java/com/fr/third/jodd/datetime/format/AbstractFormatter.java
+++ b/fine-jodd/src/main/java/com/fr/third/jodd/datetime/format/AbstractFormatter.java
@@ -25,8 +25,6 @@
package com.fr.third.jodd.datetime.format;
-import com.fr.third.jodd.datetime.DateTimeStamp;
-import com.fr.third.jodd.datetime.JDateTime;
import com.fr.third.jodd.datetime.DateTimeStamp;
import com.fr.third.jodd.datetime.JDateTime;
import com.fr.third.jodd.util.CharUtil;
@@ -49,7 +47,10 @@ import com.fr.third.jodd.util.CharUtil;
*
*
* It is not necessary to have parsers for all patterns.
+ *
+ * @deprecated jodd目前版本为5.1.6, 此版本已移除此类, 兼容问题暂不删除此类
*/
+@Deprecated
public abstract class AbstractFormatter implements JdtFormatter {
/**
diff --git a/fine-jodd/src/main/java/com/fr/third/jodd/datetime/format/Iso8601JdtFormatter.java b/fine-jodd/src/main/java/com/fr/third/jodd/datetime/format/Iso8601JdtFormatter.java
index 2720d8c2c..284def1bf 100644
--- a/fine-jodd/src/main/java/com/fr/third/jodd/datetime/format/Iso8601JdtFormatter.java
+++ b/fine-jodd/src/main/java/com/fr/third/jodd/datetime/format/Iso8601JdtFormatter.java
@@ -67,7 +67,10 @@ import java.util.TimeZone;
*
* Patterns noted with + sign are used both for conversion and parsing.
* All patterns are used for conversion.
+ *
+ * @deprecated jodd目前版本为5.1.6, 此版本已移除此类, 兼容问题暂不删除此类
*/
+@Deprecated
public class Iso8601JdtFormatter extends AbstractFormatter {
public Iso8601JdtFormatter() {
diff --git a/fine-jodd/src/main/java/com/fr/third/jodd/datetime/format/JdtFormat.java b/fine-jodd/src/main/java/com/fr/third/jodd/datetime/format/JdtFormat.java
index 73b52ac14..a40ee7439 100644
--- a/fine-jodd/src/main/java/com/fr/third/jodd/datetime/format/JdtFormat.java
+++ b/fine-jodd/src/main/java/com/fr/third/jodd/datetime/format/JdtFormat.java
@@ -27,12 +27,13 @@ package com.fr.third.jodd.datetime.format;
import com.fr.third.jodd.datetime.DateTimeStamp;
import com.fr.third.jodd.datetime.JDateTime;
-import com.fr.third.jodd.datetime.JDateTime;
-import com.fr.third.jodd.datetime.DateTimeStamp;
/**
* Immutable format-formatter pair.
+ *
+ * @deprecated jodd目前版本为5.1.6, 此版本已移除此类, 兼容问题暂不删除此类
*/
+@Deprecated
public class JdtFormat {
protected final String format;
diff --git a/fine-jodd/src/main/java/com/fr/third/jodd/datetime/format/JdtFormatter.java b/fine-jodd/src/main/java/com/fr/third/jodd/datetime/format/JdtFormatter.java
index 06ab86bf0..5d7cff1bc 100644
--- a/fine-jodd/src/main/java/com/fr/third/jodd/datetime/format/JdtFormatter.java
+++ b/fine-jodd/src/main/java/com/fr/third/jodd/datetime/format/JdtFormatter.java
@@ -25,8 +25,6 @@
package com.fr.third.jodd.datetime.format;
-import com.fr.third.jodd.datetime.DateTimeStamp;
-import com.fr.third.jodd.datetime.JDateTime;
import com.fr.third.jodd.datetime.DateTimeStamp;
import com.fr.third.jodd.datetime.JDateTime;
@@ -36,7 +34,9 @@ import java.io.Serializable;
* Date time formatter performs conversion both from and to string representation of time.
*
* @see AbstractFormatter
+ * @deprecated jodd目前版本为5.1.6, 此版本已移除此类, 兼容问题暂不删除此类
*/
+@Deprecated
public interface JdtFormatter extends Serializable {
/**
diff --git a/fine-jodd/src/main/java/com/fr/third/jodd/exception/ExceptionUtil.java b/fine-jodd/src/main/java/com/fr/third/jodd/exception/ExceptionUtil.java
index 48d00afbc..b04165fa9 100644
--- a/fine-jodd/src/main/java/com/fr/third/jodd/exception/ExceptionUtil.java
+++ b/fine-jodd/src/main/java/com/fr/third/jodd/exception/ExceptionUtil.java
@@ -28,12 +28,13 @@ package com.fr.third.jodd.exception;
import com.fr.third.jodd.io.StreamUtil;
import com.fr.third.jodd.util.StringUtil;
-import java.io.StringWriter;
import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.UndeclaredThrowableException;
+import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Collection;
-import java.sql.SQLException;
-import java.lang.reflect.InvocationTargetException;
/**
* Few exception utilities.
@@ -62,9 +63,9 @@ public class ExceptionUtil {
/**
* Returns stack trace filtered by class names.
*/
- public static StackTraceElement[] getStackTrace(Throwable t, String[] allow, String[] deny) {
+ public static StackTraceElement[] getStackTrace(final Throwable t, final String[] allow, final String[] deny) {
StackTraceElement[] st = t.getStackTrace();
- ArrayList result = new ArrayList(st.length);
+ ArrayList result = new ArrayList<>(st.length);
elementLoop:
for (StackTraceElement element : st) {
@@ -72,7 +73,7 @@ public class ExceptionUtil {
if (allow != null) {
boolean validElemenet = false;
for (String filter : allow) {
- if (className.indexOf(filter) != -1) {
+ if (className.contains(filter)) {
validElemenet = true;
break;
}
@@ -83,7 +84,7 @@ public class ExceptionUtil {
}
if (deny != null) {
for (String filter : deny) {
- if (className.indexOf(filter) != -1) {
+ if (className.contains(filter)) {
continue elementLoop;
}
}
@@ -97,8 +98,8 @@ public class ExceptionUtil {
/**
* Returns stack trace chain filtered by class names.
*/
- public static StackTraceElement[][] getStackTraceChain(Throwable t, String[] allow, String[] deny) {
- ArrayList result = new ArrayList();
+ public static StackTraceElement[][] getStackTraceChain(Throwable t, final String[] allow, final String[] deny) {
+ ArrayList result = new ArrayList<>();
while (t != null) {
StackTraceElement[] stack = getStackTrace(t, allow, deny);
result.add(stack);
@@ -116,7 +117,7 @@ public class ExceptionUtil {
* Returns exception chain starting from top up to root cause.
*/
public static Throwable[] getExceptionChain(Throwable throwable) {
- ArrayList list = new ArrayList();
+ ArrayList list = new ArrayList<>();
list.add(throwable);
while ((throwable = throwable.getCause()) != null) {
list.add(throwable);
@@ -132,7 +133,7 @@ public class ExceptionUtil {
/**
* Prints stack trace into a String.
*/
- public static String exceptionStackTraceToString(Throwable t) {
+ public static String exceptionStackTraceToString(final Throwable t) {
StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter(sw, true);
@@ -154,15 +155,17 @@ public class ExceptionUtil {
t.printStackTrace(pw);
t = t.getCause();
}
- pw.flush();
- sw.flush();
+
+ StreamUtil.close(pw);
+ StreamUtil.close(sw);
+
return sw.toString();
}
/**
* Build a message for the given base message and its cause.
*/
- public static String buildMessage(String message, Throwable cause) {
+ public static String buildMessage(final String message, Throwable cause) {
if (cause != null) {
cause = getRootCause(cause);
StringBuilder buf = new StringBuilder();
@@ -185,16 +188,24 @@ public class ExceptionUtil {
* "root" of the tree, and returns that exception. If no root cause found
* returns provided throwable.
*/
- public static Throwable getRootCause(Throwable throwable) {
+ public static Throwable getRootCause(final Throwable throwable) {
Throwable cause = throwable.getCause();
if (cause == null) {
return throwable;
}
- throwable = cause;
- while ((throwable = throwable.getCause()) != null) {
- cause = throwable;
+
+ Throwable t = throwable;
+
+ // defend against (malicious?) circularity
+ for (int i = 0; i < 1000; i++) {
+ cause = t.getCause();
+ if (cause == null) {
+ return t;
+ }
+ t = cause;
}
- return cause;
+
+ return throwable;
}
/**
@@ -202,7 +213,7 @@ public class ExceptionUtil {
* Otherwise, returns null
.
*/
@SuppressWarnings({"unchecked"})
- public static T findCause(Throwable throwable, Class cause) {
+ public static T findCause(Throwable throwable, final Class cause) {
while (throwable != null) {
if (throwable.getClass().equals(cause)) {
return (T) throwable;
@@ -216,11 +227,11 @@ public class ExceptionUtil {
// ---------------------------------------------------------------- sql
/**
- * Rolls up SQL exceptions by taking each proceeding exception
- * and making it a child of the previous using the setNextException
- * method of SQLException.
- */
- public static SQLException rollupSqlExceptions(Collection exceptions) {
+ * Rolls up SQL exceptions by taking each proceeding exception
+ * and making it a child of the previous using the setNextException
+ * method of SQLException.
+ */
+ public static SQLException rollupSqlExceptions(final Collection exceptions) {
SQLException parent = null;
for (SQLException exception : exceptions) {
if (parent != null) {
@@ -234,74 +245,57 @@ public class ExceptionUtil {
// ---------------------------------------------------------------- misc
/**
- * Throws target of InvocationTargetException
if it is exception.
+ * Throws checked exceptions in un-checked manner.
*/
- public static void throwTargetException(InvocationTargetException itex) throws Exception {
- throw extractTargetException(itex);
- }
- public static Exception extractTargetException(InvocationTargetException itex) {
- Throwable target = itex.getTargetException();
- return target instanceof Exception ? (Exception) target : itex;
+ public static void throwRuntimeException(final Throwable throwable) {
+ throw wrapToRuntimeException(throwable);
}
-
/**
- * Throws checked exceptions in un-checked manner.
- * Uses deprecated method.
- * @see #throwException(Throwable)
+ * Returns non-null
message for a throwable.
*/
- @SuppressWarnings({"deprecation"})
- public static void throwExceptionAlt(Throwable throwable) {
- if (throwable instanceof RuntimeException) {
- throw (RuntimeException) throwable;
+ public static String message(final Throwable throwable) {
+ String message = throwable.getMessage();
+
+ if (StringUtil.isBlank(message)) {
+ message = throwable.toString();
}
- throw new UnsupportedOperationException();
+
+ return message;
}
/**
- * Throws checked exceptions in un-checked manner.
- * @see #throwException(Throwable)
+ * Wraps exception to {@code RuntimeException}.
*/
- public static void throwException(Throwable throwable) {
+ public static RuntimeException wrapToRuntimeException(final Throwable throwable) {
if (throwable instanceof RuntimeException) {
- throw (RuntimeException) throwable;
+ return (RuntimeException) throwable;
}
- // can't handle these types
- if ((throwable instanceof IllegalAccessException) || (throwable instanceof InstantiationException)) {
- throw new IllegalArgumentException(throwable);
- }
-
- try {
- synchronized (ThrowableThrower.class) {
- ThrowableThrower.throwable = throwable;
- ThrowableThrower.class.newInstance();
- }
- } catch (InstantiationException iex) {
- throw new RuntimeException(iex);
- } catch (IllegalAccessException iex) {
- throw new RuntimeException(iex);
- } finally {
- ThrowableThrower.throwable = null;
+ return new RuntimeException(throwable);
+ }
+ public static Exception wrapToException(final Throwable throwable) {
+ if (throwable instanceof Exception) {
+ return (Exception) throwable;
}
+ return new RuntimeException(throwable);
}
/**
- * Returns non-null
message for a throwable.
+ * Unwraps invocation and undeclared exceptions to real cause.
*/
- public static String message(Throwable throwable) {
- String message = throwable.getMessage();
-
- if (StringUtil.isBlank(message)) {
- message = throwable.toString();
+ public static Throwable unwrapThrowable(final Throwable wrappedThrowable) {
+ Throwable unwrapped = wrappedThrowable;
+ while (true) {
+ if (unwrapped instanceof InvocationTargetException) {
+ unwrapped = ((InvocationTargetException) unwrapped).getTargetException();
+ }
+ else if (unwrapped instanceof UndeclaredThrowableException) {
+ unwrapped = ((UndeclaredThrowableException) unwrapped).getUndeclaredThrowable();
+ }
+ else {
+ return unwrapped;
+ }
}
-
- return message;
}
- private static class ThrowableThrower {
- private static Throwable throwable;
- ThrowableThrower() throws Throwable {
- throw throwable;
- }
- }
}
diff --git a/fine-jodd/src/main/java/com/fr/third/jodd/exception/UncheckedException.java b/fine-jodd/src/main/java/com/fr/third/jodd/exception/UncheckedException.java
index ada27853c..9e64ef90f 100644
--- a/fine-jodd/src/main/java/com/fr/third/jodd/exception/UncheckedException.java
+++ b/fine-jodd/src/main/java/com/fr/third/jodd/exception/UncheckedException.java
@@ -25,8 +25,11 @@
package com.fr.third.jodd.exception;
-import java.io.PrintWriter;
+import java.io.IOException;
import java.io.PrintStream;
+import java.io.PrintWriter;
+import java.io.UncheckedIOException;
+import java.util.concurrent.Callable;
/**
* Unchecked exception and also a wrapper for checked exceptions.
@@ -48,13 +51,13 @@ public class UncheckedException extends RuntimeException {
// ---------------------------------------------------------------- constructors
- public UncheckedException(Throwable t) {
+ public UncheckedException(final Throwable t) {
super(t.getMessage());
cause = t;
this.showCauseDetails = true;
}
- public UncheckedException(Throwable t, boolean showCauseDetails) {
+ public UncheckedException(final Throwable t, final boolean showCauseDetails) {
super(t.getMessage());
cause = t;
this.showCauseDetails = showCauseDetails;
@@ -66,19 +69,19 @@ public class UncheckedException extends RuntimeException {
this.showCauseDetails = false;
}
- public UncheckedException(String message) {
+ public UncheckedException(final String message) {
super(message);
cause = null;
this.showCauseDetails = false;
}
- public UncheckedException(String message, Throwable t) {
+ public UncheckedException(final String message, final Throwable t) {
super(message, t);
cause = t;
this.showCauseDetails = true;
}
- public UncheckedException(String message, Throwable t, boolean showCauseDetails) {
+ public UncheckedException(final String message, final Throwable t, final boolean showCauseDetails) {
super(message, t);
cause = t;
this.showCauseDetails = showCauseDetails;
@@ -92,7 +95,7 @@ public class UncheckedException extends RuntimeException {
}
@Override
- public void printStackTrace(PrintStream ps) {
+ public void printStackTrace(final PrintStream ps) {
synchronized (ps) {
super.printStackTrace(ps);
if ((cause != null) && showCauseDetails) {
@@ -104,7 +107,7 @@ public class UncheckedException extends RuntimeException {
}
@Override
- public void printStackTrace(PrintWriter pw) {
+ public void printStackTrace(final PrintWriter pw) {
synchronized (pw) {
super.printStackTrace(pw);
if ((cause != null) && showCauseDetails) {
@@ -131,24 +134,56 @@ public class UncheckedException extends RuntimeException {
* Wraps checked exceptions in a UncheckedException
.
* Unchecked exceptions are not wrapped.
*/
- public static RuntimeException wrapChecked(Throwable t) {
- if (t instanceof RuntimeException) {
- return (RuntimeException) t;
+ public static V callAndWrapException(final Callable callable) {
+ try {
+ return callable.call();
+ }
+ catch (IOException ioex) {
+ throw new UncheckedIOException(ioex);
+ }
+ catch (RuntimeException rtex) {
+ throw rtex;
+ }
+ catch (Exception t) {
+ throw new UncheckedException(t);
+ }
+ }
+
+ @FunctionalInterface
+ public interface CallableVoid {
+ public void call() throws Exception;
+ }
+
+ /**
+ * Wraps checked exceptions in a UncheckedException
.
+ * Unchecked exceptions are not wrapped.
+ */
+ public static void runAndWrapException(final CallableVoid callable) {
+ try {
+ callable.call();
+ }
+ catch (IOException ioex) {
+ throw new UncheckedIOException(ioex);
+ }
+ catch (RuntimeException rtex) {
+ throw rtex;
+ }
+ catch (Exception t) {
+ throw new UncheckedException(t);
}
- return new UncheckedException(t);
}
/**
* Wraps all exceptions in a UncheckedException
*/
- public static RuntimeException wrap(Throwable t) {
+ public static RuntimeException wrap(final Throwable t) {
return new UncheckedException(t);
}
/**
* Wraps all exceptions in a UncheckedException
*/
- public static RuntimeException wrap(Throwable t, String message) {
+ public static RuntimeException wrap(final Throwable t, final String message) {
return new UncheckedException(message, t);
}
@@ -173,4 +208,5 @@ public class UncheckedException extends RuntimeException {
return cause;
}
+
}
diff --git a/fine-jodd/src/main/java/com/fr/third/jodd/format/Printf.java b/fine-jodd/src/main/java/com/fr/third/jodd/format/Printf.java
deleted file mode 100644
index 17b93ba70..000000000
--- a/fine-jodd/src/main/java/com/fr/third/jodd/format/Printf.java
+++ /dev/null
@@ -1,113 +0,0 @@
-// Copyright (c) 2003-present, Jodd Team (http://jodd.org)
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are met:
-//
-// 1. Redistributions of source code must retain the above copyright notice,
-// this list of conditions and the following disclaimer.
-//
-// 2. Redistributions in binary form must reproduce the above copyright
-// notice, this list of conditions and the following disclaimer in the
-// documentation and/or other materials provided with the distribution.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
-// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-// POSSIBILITY OF SUCH DAMAGE.
-
-package com.fr.third.jodd.format;
-
-/**
- * Printf.
- * @see PrintfFormat
- */
-public class Printf {
-
- // ---------------------------------------------------------------- primitives
-
- /**
- * @see PrintfFormat#form(byte)
- */
- public static String str(String format, byte value) {
- return new PrintfFormat(format).form(value);
- }
-
- /**
- * @see PrintfFormat#form(char)
- */
- public static String str(String format, char value) {
- return new PrintfFormat(format).form(value);
- }
-
- /**
- * @see PrintfFormat#form(short)
- */
- public static String str(String format, short value) {
- return new PrintfFormat(format).form(value);
- }
-
- /**
- * @see PrintfFormat#form(int)
- */
- public static String str(String format, int value) {
- return new PrintfFormat(format).form(value);
- }
-
- /**
- * @see PrintfFormat#form(long)
- */
- public static String str(String format, long value) {
- return new PrintfFormat(format).form(value);
- }
-
- /**
- * @see PrintfFormat#form(double)
- */
- public static String str(String format, float value) {
- return new PrintfFormat(format).form(value);
- }
-
- /**
- * @see PrintfFormat#form(double)
- */
- public static String str(String format, double value) {
- return new PrintfFormat(format).form(value);
- }
-
- /**
- * @see PrintfFormat#form(boolean)
- */
- public static String str(String format, boolean value) {
- return new PrintfFormat(format).form(value);
- }
-
- // ---------------------------------------------------------------- objects
-
- public static String str(String format, String value) {
- return new PrintfFormat(format).form(value);
- }
-
- public static String str(String format, Object param) {
- return new PrintfFormat(format).form(param);
- }
-
- // ---------------------------------------------------------------- multiple objects
-
- public static String str(String format, Object... params) {
- PrintfFormat pf = new PrintfFormat();
- for (Object param : params) {
- pf.reinit(format);
- format = pf.form(param);
- }
- return format;
- }
-
-}
\ No newline at end of file
diff --git a/fine-jodd/src/main/java/com/fr/third/jodd/format/PrintfFormat.java b/fine-jodd/src/main/java/com/fr/third/jodd/format/PrintfFormat.java
deleted file mode 100644
index 63d067c16..000000000
--- a/fine-jodd/src/main/java/com/fr/third/jodd/format/PrintfFormat.java
+++ /dev/null
@@ -1,766 +0,0 @@
-// Copyright (c) 2003-present, Jodd Team (http://jodd.org)
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are met:
-//
-// 1. Redistributions of source code must retain the above copyright notice,
-// this list of conditions and the following disclaimer.
-//
-// 2. Redistributions in binary form must reproduce the above copyright
-// notice, this list of conditions and the following disclaimer in the
-// documentation and/or other materials provided with the distribution.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
-// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-// POSSIBILITY OF SUCH DAMAGE.
-
-package com.fr.third.jodd.format;
-
-import com.fr.third.jodd.util.StringPool;
-
-import java.math.BigInteger;
-
-/**
- * Fast simple and yet useful formatting.
- */
-public class PrintfFormat {
-
- protected int width;
- protected int precision;
- protected StringBuilder pre;
- protected StringBuilder post;
- protected boolean leadingZeroes;
- protected boolean showPlus;
- protected boolean alternate;
- protected boolean showSpace;
- protected boolean leftAlign;
- protected boolean groupDigits;
- protected char fmt; // one of cdeEfgGiosxXos...
- protected boolean countSignInLen;
- private static final BigInteger bgInt = new BigInteger("9223372036854775808"); // 2^63
-
- /**
- * Formats a number in a printf format, like C.
- *
- * @param s the format string following printf format string
- * The string has a prefix, a format code and a suffix. The prefix and suffix
- * become part of the formatted output. The format code directs the
- * formatting of the (single) parameter to be formatted. The code has the
- * following structure
- *
- * - a % (required)
- *
- *
- a modifier (optional)
- *
- * - +
- forces display of + for positive numbers
- *
- ~
- do not count leading + or - in length
- *
- 0
- show leading zeroes
- *
- -
- align left in the field
- *
- space
- prepend a space in front of positive numbers
- *
- #
- use "alternate" format. Add 0 or 0x for octal or hexadecimal numbers;
- * add 0b for binary numbers. Don't suppress trailing zeroes in general floating
- * point format.
- *
- ,
- groups decimal values by thousands (for 'diuxXb' formats)
- *
- *
- * - an integer denoting field width (optional)
- *
- *
- a period (.) followed by an integer denoting precision (optional)
- *
- *
- a format descriptor (required)
- *
- * - f
- floating point number in fixed format,
- *
- e, E
- floating point number in exponential notation (scientific format).
- * The E format results in an uppercase E for the exponent (1.14130E+003), the e
- * format in a lowercase e,
- *
- g, G
- floating point number in general format (fixed format for small
- * numbers, exponential format for large numbers). Trailing zeroes are suppressed.
- * The G format results in an uppercase E for the exponent (if any), the g format
- * in a lowercase e,.
- *
- d, i
- signed long and integer in decimal,
- *
- u
- unsigned long or integer in decimal,
- *
- x
- unsigned long or integer in hexadecimal,
- *
- o
- unsigned long or integer in octal,
- *
- b
- unsigned long or integer in binary,
- *
- s
- string (actually,
toString()
value of an object),
- * - c
- character,
- *
- l, L
- boolean in lower or upper case (for booleans and int/longs),
- *
- p
- identity hash code of an object (pointer :).
- *
- *
- */
- public PrintfFormat(String s) {
- init(s, 0);
- }
-
- /**
- * For internal use with {@link #init(String, int)} and {@link #reinit(String)}.
- */
- protected PrintfFormat() {
- }
-
- protected PrintfFormat reinit(String s) {
- if (pre == null) {
- init(s, 0);
- } else {
- init(s, pre.length());
- }
- return this;
- }
-
- protected void init(String s, int i) {
- width = 0;
- precision = -1;
- pre = (i == 0 ? new StringBuilder() : new StringBuilder(s.substring(0, i)));
- post = new StringBuilder();
- leadingZeroes = false;
- showPlus = false;
- alternate = false;
- showSpace = false;
- leftAlign = false;
- countSignInLen = true;
- fmt = ' ';
-
- int length = s.length();
- int parseState; // 0 = prefix, 1 = flags, 2 = width, 3 = precision, 4 = format, 5 = end
-
- // 0: parse string prefix upto first '%'.
- while (true) {
- if (i >= length) {
- throw new IllegalArgumentException("Format string requires '%'.");
- }
- char c = s.charAt(i);
- if (c != '%') {
- pre.append(c);
- i++;
- continue;
- }
- if (i >= length - 1) {
- throw new IllegalArgumentException("Format string can not end with '%'.");
- }
- if (s.charAt(i + 1) == '%') { // double '%%'
- pre.append('%');
- i += 2;
- continue;
- }
- //parseState = 1; // single $ founded
- i++;
- break;
- }
-
- // 1: parse flags
- flagsloop:
- //while (parseState == 1) {
- while (true) {
- if (i >= length) {
- parseState = 5;
- break;
- }
- char c = s.charAt(i);
- switch (c) {
- case ' ': showSpace = true; break;
- case '-': leftAlign = true; break;
- case '+': showPlus = true; break;
- case '0': leadingZeroes = true; break;
- case '#': alternate = true; break;
- case '~': countSignInLen = false; break;
- case ',': groupDigits = true; break;
- default:
- parseState = 2;
- break flagsloop;
- }
- i++;
- }
-
- // 2: parse width
- while (parseState == 2) {
- if (i >= length) {
- parseState = 5;
- break;
- }
- char c = s.charAt(i);
- if ((c >= '0') && (c <= '9')) {
- width = (width * 10) + s.charAt(i) - '0';
- i++;
- continue;
- }
- if (s.charAt(i) == '.') {
- parseState = 3;
- precision = 0;
- i++;
- } else {
- parseState = 4;
- }
- break;
- }
-
- // 3: parse precision
- while (parseState == 3) {
- if (i >= length) {
- parseState = 5;
- break;
- }
- char c = s.charAt(i);
- if ((c >= '0') && (c <= '9')) {
- precision = (precision * 10) + s.charAt(i) - '0';
- i++;
- continue;
- }
- parseState = 4;
- break;
- }
-
- // 4: parse format
- if (parseState == 4) {
- if (i < length) {
- fmt = s.charAt(i);
- i++;
-// } else {
-// parseState = 5;
- }
- }
-
- // append suffix
- if (i < length) {
- post.append(s.substring(i, length));
- }
- }
-
- /**
- * Formats a double with exp format.
- */
- protected String expFormat(double d) {
- StringBuilder f = new StringBuilder();
- int e = 0;
- double dd = d;
- double factor = 1;
-
- if (d != 0) {
- while (dd > 10) {
- e++;
- factor /= 10;
- dd /= 10;
- }
- while (dd < 1) {
- e--;
- factor *= 10;
- dd *= 10;
- }
- }
- if (((fmt == 'g') || (fmt == 'G')) && (e >= -4) && (e < precision)) {
- return fixedFormat(d);
- }
-
- d *= factor;
- f.append(fixedFormat(d));
-
- if (fmt == 'e' || fmt == 'g') {
- f.append('e');
- } else {
- f.append('E');
- }
-
- StringBuilder p = new StringBuilder("000");
- if (e >= 0) {
- f.append('+');
- p.append(e);
- } else {
- f.append('-');
- p.append(-e);
- }
-
- char[] data = new char[3];
- p.getChars(p.length() - 3, p.length(), data, 0);
- return f.append(data).toString();
- }
-
- /**
- * Formats a double with fixed format.
- */
- protected String fixedFormat(double d) {
- boolean removeTrailing = (fmt == 'G' || fmt == 'g') && !alternate;
-
- // remove trailing zeroes and decimal point
- if (d > 0x7FFFFFFFFFFFFFFFL) {
- return expFormat(d);
- }
- if (precision == 0) {
- return Long.toString(Math.round(d));
- }
-
- long whole = (long) d;
- double fr = d - whole; // fractional part
-
- if (fr >= 1 || fr < 0) {
- return expFormat(d);
- }
-
- double factor = 1;
- StringBuilder leadingZeroesStr = new StringBuilder();
-
- for (int i = 1; i <= precision && factor <= 0x7FFFFFFFFFFFFFFFL; i++) {
- factor *= 10;
- leadingZeroesStr.append('0');
- }
-
- long l = Math.round(factor * fr);
- if (l >= factor) {
- l = 0;
- whole++;
- }
-
- String z = leadingZeroesStr.toString() + l;
- z = '.' + z.substring(z.length() - precision, z.length());
-
- if (removeTrailing) {
- int t = z.length() - 1;
- while (t >= 0 && z.charAt(t) == '0') {
- t--;
- }
- if (t >= 0 && z.charAt(t) == '.') {
- t--;
- }
- z = z.substring(0, t + 1);
- }
- return whole + z;
- }
-
- /**
- * Pads the value with spaces and adds prefix and suffix.
- */
- protected String pad(String value) {
- String spaces = repeat(' ', width - value.length());
- if (leftAlign) {
- return pre + value + spaces + post;
- } else {
- return pre + spaces + value + post;
- }
- }
-
- /**
- * Returns new string created by repeating a single character.
- */
- protected static String repeat(char c, int n) {
- if (n <= 0) {
- return (StringPool.EMPTY);
- }
- char[] buffer = new char[n];
- for (int i = 0; i < n; i++) {
- buffer[i] = c;
- }
- return new String(buffer);
- }
-
- private String getAltPrefixFor(char fmt, String currentPrefix) {
- switch(fmt) {
- case 'x':
- return "0x";
- case 'X':
- return "0X";
- case 'b':
- return "0b";
- case 'B':
- return "0B";
- default:
- return currentPrefix;
- }
- }
-
- protected String sign(int s, String r) {
- String p = StringPool.EMPTY;
-
- if (s < 0) {
- p = StringPool.DASH;
- } else if (s > 0) {
- if (showPlus) {
- p = StringPool.PLUS;
- } else if (showSpace) {
- p = StringPool.SPACE;
- }
- } else {
- if (alternate) {
- if (fmt == 'o' && r.length() > 0 && r.charAt(0) != '0') {
- p = "0";
- } else {
- p = getAltPrefixFor(fmt, p);
- }
- }
- }
-
- int w = 0;
-
- if (leadingZeroes) {
- w = width;
- } else if ((fmt == 'u' || fmt == 'd' || fmt == 'i' || fmt == 'x' || fmt == 'X' || fmt == 'o') && precision > 0) {
- w = precision;
- }
-
- if (countSignInLen) {
- return p + repeat('0', w - p.length() - r.length()) + r;
- } else {
- return p + repeat('0', w - r.length()) + r;
- }
- }
-
- /**
- * Groups numbers by inserting 'separator' after every group of 'size' digits,
- * starting from the right.
- */
- protected String groupDigits(String value, int size, char separator) {
- if (!groupDigits) {
- return value;
- }
- StringBuilder r = new StringBuilder(value.length() + 10);
- int ndx = 0;
- int len = value.length() - 1;
- int mod = len % size;
- while (ndx < len) {
- r.append(value.charAt(ndx));
- if (mod == 0) {
- r.append(separator);
- mod = size;
- }
- mod--;
- ndx++;
- }
- r.append(value.charAt(ndx));
- return r.toString();
- }
-
-
-
- // ---------------------------------------------------------------- public form methods
-
- /**
- * Formats a character into a string (like sprintf in C).
- */
- public String form(char value) {
- switch(fmt) {
- case 'c':
- return alternate ? "\\u" + Integer.toHexString((int) value & 0xFFFF) : pad(String.valueOf(value));
- case 'C':
- return alternate ? "\\u" + Integer.toHexString((int) value & 0xFFFF).toUpperCase() : pad(String.valueOf(value));
- case 'd':
- case 'i':
- case 'u':
- case 'o':
- case 'x':
- case 'X':
- case 'b':
- case 'l':
- case 'L':
- return form((short) value);
- default:
- throw newIllegalArgumentException("cCdiuoxXblL");
- }
- }
-
- /**
- * Formats a boolean into a string (like sprintf in C).
- */
- public String form(boolean value) {
- if (fmt == 'l') {
- return pad(value ? "true" : "false");
- }
- if (fmt == 'L') {
- return pad(value ? "TRUE" : "FALSE");
- }
- throw newIllegalArgumentException("lL");
-
- }
-
- /**
- * Formats a double into a string (like sprintf in C).
- */
- public String form(double x) {
- String r;
-
- if (precision < 0) {
- precision = 6;
- }
-
- int s = 1;
- if (x < 0) {
- x = -x;
- s = -1;
- }
- if (fmt == 'f') {
- r = fixedFormat(x);
- } else if (fmt == 'e' || fmt == 'E' || fmt == 'g' || fmt == 'G') {
- r = expFormat(x);
- } else {
- throw newIllegalArgumentException("feEgG");
- }
- return pad(sign(s, r));
- }
-
- /**
- * Formats a long integer into a string (like sprintf in C).
- */
- public String form(long x) {
- String r;
- int s = 0;
-
- switch (fmt) {
- case 'c':
- return form((char) x);
- case 'd':
- if (x < 0) {
- r = Long.toString(x).substring(1);
- s = -1;
- } else {
- r = Long.toString(x);
- s = 1;
- }
- r = groupDigits(r, 3, ',');
- break;
- case 'i':
- int xx = (int) x;
- if (xx < 0) {
- r = Integer.toString(xx).substring(1);
- s = -1;
- } else {
- r = Integer.toString(xx);
- s = 1;
- }
- r = groupDigits(r, 3, ',');
- break;
- case 'u':
- if (x < 0) {
- long xl = x & 0x7FFFFFFFFFFFFFFFL;
- r = Long.toString(xl);
- BigInteger bi = new BigInteger(r);
- r = bi.add(bgInt).toString();
- } else {
- r = Long.toString(x);
- }
- r = groupDigits(r, 3, ',');
- s = 1;
- break;
- case 'o':
- r = Long.toOctalString(x);
- break;
- case 'x':
- r = Long.toHexString(x);
- r = groupDigits(r, 4, ' ');
- break;
- case 'X':
- r = Long.toHexString(x).toUpperCase();
- r = groupDigits(r, 4, ' ');
- break;
- case 'b':
- case 'B':
- r = Long.toBinaryString(x);
- r = groupDigits(r, 8, ' ');
- break;
- case 'l':
- r = (x == 0 ? "false" : "true");
- break;
- case 'L':
- r = (x == 0 ? "FALSE" : "TRUE");
- break;
- default:
- throw new IllegalArgumentException("cdiuoxXbBlL");
- }
-
- return pad(sign(s, r));
- }
-
- /**
- * Formats an integer into a string (like sprintf in C).
- */
- public String form(int x) {
- String r;
- int s = 0;
-
- switch (fmt) {
- case 'c':
- return form((char) x);
- case 'd':
- case 'i':
- if (x < 0) {
- r = Integer.toString(x).substring(1);
- s = -1;
- } else {
- r = Integer.toString(x);
- s = 1;
- }
- r = groupDigits(r, 3, ',');
- break;
- case 'u':
- long xl = x & 0x00000000FFFFFFFFL;
- r = Long.toString(xl);
- r = groupDigits(r, 3, ',');
- s = 1;
- break;
- case 'o':
- r = Integer.toOctalString(x);
- break;
- case 'x':
- r = Integer.toHexString(x);
- r = groupDigits(r, 4, ' ');
- break;
- case 'X':
- r = Integer.toHexString(x).toUpperCase();
- r = groupDigits(r, 4, ' ');
- break;
- case 'b':
- case 'B':
- r = Integer.toBinaryString(x);
- r = groupDigits(r, 8, ' ');
- break;
- case 'l':
- r = (x == 0 ? "false" : "true");
- break;
- case 'L':
- r = (x == 0 ? "FALSE" : "TRUE");
- break;
- default:
- throw newIllegalArgumentException("cdiuoxXbBlL");
- }
- return pad(sign(s, r));
- }
-
- /**
- * Formats a byte into a string (like sprintf in C).
- */
- public String form(byte b) {
- return formInt(b, 0xFF);
- }
-
- /**
- * Formats a short into a string (like sprintf in C).
- */
- public String form(short s) {
- return formInt(s, 0xFFFF);
- }
-
- /**
- * Formatter for both byte
and short
values.
- */
- private String formInt(int value, int unsignedMask) {
- String r;
- int s = 0;
-
- switch (fmt) {
- case 'c':
- return form((char) value);
- case 'd':
- case 'i':
- if (value < 0) {
- r = Integer.toString(value).substring(1);
- s = -1;
- } else {
- r = Integer.toString(value);
- s = 1;
- }
- r = groupDigits(r, 3, ',');
- break;
- case 'u':
- int xl = value & unsignedMask;
- r = Integer.toString(xl);
- r = groupDigits(r, 3, ',');
- s = 1;
- break;
- case 'o':
- r = Integer.toOctalString(value & unsignedMask);
- break;
- case 'x':
- r = Integer.toHexString(value & unsignedMask);
- r = groupDigits(r, 4, ' ');
- break;
- case 'X':
- r = Integer.toHexString(value & unsignedMask).toUpperCase();
- r = groupDigits(r, 4, ' ');
- break;
- case 'b':
- case 'B':
- r = Integer.toBinaryString(value & unsignedMask);
- r = groupDigits(r, 8, ' ');
- break;
- case 'l':
- r = (value == 0 ? "false" : "true");
- break;
- case 'L':
- r = (value == 0 ? "FALSE" : "TRUE");
- break;
- default:
- throw newIllegalArgumentException("cdiuoxXblL");
- }
- return pad(sign(s, r));
- }
-
- /**
- * Formats a object into a string depending on format (like sprintf in C).
- * If object is a numeric type and format is not one object formats (like 's' or 'p')
- * it will be converted to primitive and formatted as such.
- */
- public String form(Object object) {
- if (object == null) {
- return StringPool.NULL;
- }
-
- switch (fmt) {
- case 's' :
- String s = object.toString();
- if (precision >= 0 && precision < s.length()) {
- s = s.substring(0, precision);
- }
- return pad(s);
- case 'p' :
- return Integer.toString(System.identityHashCode(object));
- }
-
- // check for numeric type
- if (object instanceof Number) {
- Number number = (Number) object;
- if (object instanceof Integer) {
- return form(number.intValue());
- }
- if (object instanceof Long) {
- return form(number.longValue());
- }
- if (object instanceof Double) {
- return form(number.doubleValue());
- }
- if (object instanceof Float) {
- return form(number.floatValue());
- }
- if (object instanceof Byte) {
- return form(number.byteValue());
- }
- if (object instanceof Short) {
- return form(number.shortValue());
- }
- else {
- return form(number.intValue());
- }
- }
- else if (object instanceof Character) {
- return form(((Character) object).charValue());
- }
- else if (object instanceof Boolean) {
- return form(((Boolean)object).booleanValue());
- }
-
- // throw exception about invalid 'object'-formats
- throw newIllegalArgumentException("sp");
- }
-
- /**
- * Creates IllegalArgumentException
with message.
- */
- protected IllegalArgumentException newIllegalArgumentException(String allowedFormats) {
- return new IllegalArgumentException("Invalid format: '" + fmt + "' is not one of '" + allowedFormats + "'");
- }
-
-}
\ No newline at end of file
diff --git a/fine-jodd/src/main/java/com/fr/third/jodd/util/InExRuleMatcher.java b/fine-jodd/src/main/java/com/fr/third/jodd/inex/InExRuleMatcher.java
similarity index 68%
rename from fine-jodd/src/main/java/com/fr/third/jodd/util/InExRuleMatcher.java
rename to fine-jodd/src/main/java/com/fr/third/jodd/inex/InExRuleMatcher.java
index 2b6372f2c..398d17cb4 100644
--- a/fine-jodd/src/main/java/com/fr/third/jodd/util/InExRuleMatcher.java
+++ b/fine-jodd/src/main/java/com/fr/third/jodd/inex/InExRuleMatcher.java
@@ -23,32 +23,29 @@
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
-package com.fr.third.jodd.util;
+package com.fr.third.jodd.inex;
+
+import com.fr.third.jodd.util.Wildcard;
/**
* Rule matcher.
*/
+@FunctionalInterface
public interface InExRuleMatcher {
/**
- * {@link jodd.util.Wildcard#match(String, String) Wilcard} rule matcher.
+ * {@link com.fr.third.jodd.util.Wildcard#match(CharSequence, CharSequence) Wilcard} rule matcher.
*/
- public static final InExRuleMatcher WILDCARD_RULE_MATCHER = new InExRuleMatcher() {
- public boolean accept(String value, String rule, boolean include) {
- return Wildcard.match(value, rule);
- }
- };
+ InExRuleMatcher WILDCARD_RULE_MATCHER =
+ (value, rule, include) -> Wildcard.match(value, rule);
/**
- * {@link jodd.util.Wildcard#matchPath(String, String) Wilcard path} rule matcher.
+ * {@link com.fr.third.jodd.util.Wildcard#matchPath(String, String) Wilcard path} rule matcher.
*/
- public static final InExRuleMatcher WILDCARD_PATH_RULE_MATCHER = new InExRuleMatcher() {
- public boolean accept(String value, String rule, boolean include) {
- return Wildcard.matchPath(value, rule);
- }
- };
+ InExRuleMatcher WILDCARD_PATH_RULE_MATCHER =
+ (value, rule, include) -> Wildcard.matchPath(value, rule);
/**
- * Match the value against the rule.
+ * Matches the value against the rule.
*/
boolean accept(T value, R rule, boolean include);
diff --git a/fine-jodd/src/main/java/com/fr/third/jodd/util/InExRules.java b/fine-jodd/src/main/java/com/fr/third/jodd/inex/InExRules.java
similarity index 83%
rename from fine-jodd/src/main/java/com/fr/third/jodd/util/InExRules.java
rename to fine-jodd/src/main/java/com/fr/third/jodd/inex/InExRules.java
index e83a12c3a..579c64e04 100644
--- a/fine-jodd/src/main/java/com/fr/third/jodd/util/InExRules.java
+++ b/fine-jodd/src/main/java/com/fr/third/jodd/inex/InExRules.java
@@ -23,13 +23,13 @@
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
-package com.fr.third.jodd.util;
+package com.fr.third.jodd.inex;
import java.util.ArrayList;
import java.util.List;
/**
- * One-class rule engine for includes/excludes logic. It can be used when
+ * A single-class rule engine for includes/excludes filtering logic. It can be used when
* set of objects has to filtered using includes and excludes rules.
* For example, when filtering files by file name etc.
*
@@ -50,11 +50,18 @@ import java.util.List;
*
* All Jodd classes that filters something uses this class to unify the
* behavior across the Jodd library.
+ *
+ * About generics: rule engine examine Values (V). Rules are defined as Definitions (D).
+ * They are stored internally as R, that is used with Values.
*/
-public class InExRules implements InExRuleMatcher {
+public class InExRules implements InExRuleMatcher {
+
+ public InExRules create() {
+ return new InExRules<>();
+ }
protected List> rules;
- protected final InExRuleMatcher inExRuleMatcher;
+ protected final InExRuleMatcher inExRuleMatcher;
protected int includesCount;
protected int excludesCount;
protected boolean blacklist = true;
@@ -69,7 +76,7 @@ public class InExRules implements InExRuleMatcher {
/**
* Creates instance that uses provided matcher.
*/
- public InExRules(InExRuleMatcher inExRuleMatcher) {
+ public InExRules(final InExRuleMatcher inExRuleMatcher) {
this.inExRuleMatcher = inExRuleMatcher;
}
@@ -114,7 +121,7 @@ public class InExRules implements InExRuleMatcher {
public final R value;
public final boolean include;
- public Rule(R value, boolean include) {
+ public Rule(final R value, final boolean include) {
this.value = value;
this.include = include;
}
@@ -125,7 +132,7 @@ public class InExRules implements InExRuleMatcher {
}
@Override
- public boolean equals(Object o) {
+ public boolean equals(final Object o) {
if (this == o) {
return true;
}
@@ -156,7 +163,7 @@ public class InExRules implements InExRuleMatcher {
/**
* Returns rule's value on given index.
*/
- public R getRule(int index) {
+ public R getRule(final int index) {
return rules.get(index).value;
}
@@ -211,7 +218,7 @@ public class InExRules implements InExRuleMatcher {
*
* Should be called after all the rules are set, before matching starts.
*/
- public void smartMode() {
+ public void detectMode() {
if (excludesCount == 0 && includesCount > 0) {
whitelist();
}
@@ -223,23 +230,23 @@ public class InExRules implements InExRuleMatcher {
/**
* Adds include rule.
*/
- public void include(R rule) {
+ public void include(final D rule) {
addRule(rule, true);
}
/**
* Adds exclude rule.
*/
- public void exclude(R rule) {
+ public void exclude(final D rule) {
addRule(rule, false);
}
/**
* Adds a rule. Duplicates are not allowed and will be ignored.
*/
- protected void addRule(R rule, boolean include) {
+ protected void addRule(final D ruleDefinition, final boolean include) {
if (rules == null) {
- rules = new ArrayList>();
+ rules = new ArrayList<>();
}
if (include) {
@@ -248,7 +255,7 @@ public class InExRules implements InExRuleMatcher {
excludesCount++;
}
- Rule newRule = new Rule(rule, include);
+ Rule newRule = new Rule<>(makeRule(ruleDefinition), include);
if (rules.contains(newRule)) {
return;
@@ -257,16 +264,20 @@ public class InExRules implements InExRuleMatcher {
rules.add(newRule);
}
+ protected R makeRule(final D rule) {
+ return (R) rule;
+ }
+
/**
* Matches value against the set of rules using current white/black list mode.
*/
- public boolean match(T value) {
+ public boolean match(final V value) {
return match(value, blacklist);
}
/**
* Matches value against the set of rules using provided white/black list mode.
*/
- public boolean match(T value, boolean blacklist) {
+ public boolean match(final V value, final boolean blacklist) {
if (rules == null) {
return blacklist;
}
@@ -289,7 +300,7 @@ public class InExRules implements InExRuleMatcher {
* Applies rules on given flag using current black/white list mode.
* @see #apply(Object, boolean, boolean)
*/
- public boolean apply(T value, boolean flag) {
+ public boolean apply(final V value, final boolean flag) {
return apply(value, blacklist, flag);
}
@@ -299,7 +310,7 @@ public class InExRules implements InExRuleMatcher {
* chain several rules and have the rule engine change the flag
* only when a rule is matched.
*/
- public boolean apply(T value, final boolean blacklist, boolean flag) {
+ public boolean apply(final V value, final boolean blacklist, boolean flag) {
if (rules == null) {
return flag;
}
@@ -319,7 +330,7 @@ public class InExRules implements InExRuleMatcher {
/**
* Process includes rules.
*/
- protected boolean processIncludes(T value, boolean include) {
+ protected boolean processIncludes(final V value, boolean include) {
if (includesCount > 0) {
if (!include) {
for (Rule rule : rules) {
@@ -340,7 +351,7 @@ public class InExRules implements InExRuleMatcher {
/**
* Process excludes rules.
*/
- protected boolean processExcludes(T value, boolean include) {
+ protected boolean processExcludes(final V value, boolean include) {
if (excludesCount > 0) {
if (include) {
for (Rule rule : rules) {
@@ -362,7 +373,8 @@ public class InExRules implements InExRuleMatcher {
* Matches value against single rule. By default performs equals
on value
* against the rule.
*/
- public boolean accept(T value, R rule, boolean include) {
+ @Override
+ public boolean accept(final V value, final R rule, final boolean include) {
return value.equals(rule);
}
diff --git a/fine-jodd/src/main/java/com/fr/third/jodd/io/filter/package-info.java b/fine-jodd/src/main/java/com/fr/third/jodd/inex/package-info.java
similarity index 95%
rename from fine-jodd/src/main/java/com/fr/third/jodd/io/filter/package-info.java
rename to fine-jodd/src/main/java/com/fr/third/jodd/inex/package-info.java
index a1722ff41..bcd7e7694 100644
--- a/fine-jodd/src/main/java/com/fr/third/jodd/io/filter/package-info.java
+++ b/fine-jodd/src/main/java/com/fr/third/jodd/inex/package-info.java
@@ -24,6 +24,6 @@
// POSSIBILITY OF SUCH DAMAGE.
/**
- * Various file filters.
+ * Include-Exclude rules engine.
*/
-package com.fr.third.jodd.io.filter;
\ No newline at end of file
+package com.fr.third.jodd.inex;
\ No newline at end of file
diff --git a/fine-jodd/src/main/java/com/fr/third/jodd/introspector/CachingIntrospector.java b/fine-jodd/src/main/java/com/fr/third/jodd/introspector/CachingIntrospector.java
index a00160e8f..a1fb1342e 100644
--- a/fine-jodd/src/main/java/com/fr/third/jodd/introspector/CachingIntrospector.java
+++ b/fine-jodd/src/main/java/com/fr/third/jodd/introspector/CachingIntrospector.java
@@ -25,18 +25,17 @@
package com.fr.third.jodd.introspector;
-import java.util.HashMap;
-import java.util.Map;
+import com.fr.third.jodd.cache.TypeCache;
/**
- * Default {@link com.fr.third.jodd.introspector.Introspector introspector} that caches all class descriptors.
+ * Default {@link com.fr.third.jodd.introspector.ClassIntrospector introspector} that caches all class descriptors.
* It can examine either accessible or supported fields/methods/constructors.
*
* It simply caches all class descriptors.
*/
-public class CachingIntrospector implements Introspector {
+public class CachingIntrospector implements ClassIntrospector {
- protected final Map cache;
+ protected final TypeCache cache;
protected final boolean scanAccessible;
protected final boolean enhancedProperties;
protected final boolean includeFieldsAsProperties;
@@ -50,12 +49,12 @@ public class CachingIntrospector implements Introspector {
}
/**
- * Creates new caching {@link Introspector}. It may scan
+ * Creates new caching {@link ClassIntrospector}. It may scan
* accessible or supported fields, methods or
* constructors.
*/
- public CachingIntrospector(boolean scanAccessible, boolean enhancedProperties, boolean includeFieldsAsProperties, String[] propertyFieldPrefix) {
- this.cache = new HashMap();
+ public CachingIntrospector(final boolean scanAccessible, final boolean enhancedProperties, final boolean includeFieldsAsProperties, final String[] propertyFieldPrefix) {
+ this.cache = TypeCache.createDefault();
this.scanAccessible = scanAccessible;
this.enhancedProperties = enhancedProperties;
this.includeFieldsAsProperties = includeFieldsAsProperties;
@@ -65,39 +64,23 @@ public class CachingIntrospector implements Introspector {
/**
* {@inheritDoc}
*/
- public ClassDescriptor lookup(Class type) {
- ClassDescriptor cd = cache.get(type);
- if (cd != null) {
- cd.increaseUsageCount();
- return cd;
- }
- cd = describeClass(type);
- cache.put(type, cd);
- return cd;
- }
-
- /**
- * {@inheritDoc}
- */
- public ClassDescriptor register(Class type) {
- ClassDescriptor cd = describeClass(type);
- cache.put(type, cd);
- return cd;
- }
-
- /**
- * Describes a class by creating a new instance of {@link ClassDescriptor}
- * that examines all accessible methods and fields.
- */
- protected ClassDescriptor describeClass(Class type) {
- return new ClassDescriptor(type, scanAccessible, enhancedProperties, includeFieldsAsProperties, propertyFieldPrefix);
+ @Override
+ public ClassDescriptor lookup(final Class type) {
+ return cache.get(type, (t) ->
+ new ClassDescriptor(
+ t,
+ scanAccessible,
+ enhancedProperties,
+ includeFieldsAsProperties,
+ propertyFieldPrefix));
}
/**
* {@inheritDoc}
*/
+ @Override
public void reset() {
cache.clear();
}
-}
\ No newline at end of file
+}
diff --git a/fine-jodd/src/main/java/com/fr/third/jodd/introspector/ClassDescriptor.java b/fine-jodd/src/main/java/com/fr/third/jodd/introspector/ClassDescriptor.java
index 4cd821741..a63608000 100644
--- a/fine-jodd/src/main/java/com/fr/third/jodd/introspector/ClassDescriptor.java
+++ b/fine-jodd/src/main/java/com/fr/third/jodd/introspector/ClassDescriptor.java
@@ -25,13 +25,13 @@
package com.fr.third.jodd.introspector;
-import com.fr.third.jodd.util.ReflectUtil;
-import com.fr.third.jodd.util.ReflectUtil;
+import com.fr.third.jodd.util.ClassUtil;
-import java.util.Map;
+import java.util.Collection;
import java.util.List;
+import java.util.Map;
import java.util.Set;
-import java.util.Collection;
+import java.util.function.Supplier;
/**
* A descriptor class for all methods/fields/properties/constructors of a class.
@@ -59,9 +59,8 @@ public class ClassDescriptor {
protected final String[] propertyFieldPrefix;
protected final Class[] interfaces;
protected final Class[] superclasses;
- protected int usageCount;
- public ClassDescriptor(Class type, boolean scanAccessible, boolean extendedProperties, boolean includeFieldsAsProperties, String[] propertyFieldPrefix) {
+ public ClassDescriptor(final Class type, final boolean scanAccessible, final boolean extendedProperties, final boolean includeFieldsAsProperties, final String[] propertyFieldPrefix) {
this.type = type;
this.scanAccessible = scanAccessible;
this.extendedProperties = extendedProperties;
@@ -69,13 +68,17 @@ public class ClassDescriptor {
this.propertyFieldPrefix = propertyFieldPrefix;
isArray = type.isArray();
- isMap = ReflectUtil.isTypeOf(type, Map.class);
- isList = ReflectUtil.isTypeOf(type, List.class);
- isSet = ReflectUtil.isTypeOf(type, Set.class);
- isCollection = ReflectUtil.isTypeOf(type, Collection.class);
+ isMap = ClassUtil.isTypeOf(type, Map.class);
+ isList = ClassUtil.isTypeOf(type, List.class);
+ isSet = ClassUtil.isTypeOf(type, Set.class);
+ isCollection = ClassUtil.isTypeOf(type, Collection.class);
+ isSupplier = ClassUtil.isTypeOf(type, Supplier.class);
+
+ interfaces = ClassUtil.resolveAllInterfaces(type);
+ superclasses = ClassUtil.resolveAllSuperclasses(type);
- interfaces = ReflectUtil.resolveAllInterfaces(type);
- superclasses = ReflectUtil.resolveAllSuperclasses(type);
+ isSystemClass = type.getName().startsWith("java.") &&
+ !type.getName().startsWith("java.awt.geom.");
}
/**
@@ -118,23 +121,6 @@ public class ClassDescriptor {
return propertyFieldPrefix;
}
- /**
- * Increases usage count.
- */
- protected void increaseUsageCount() {
- usageCount++;
- }
-
- /**
- * Returns number of class descriptor usages. That is number
- * of times when class descriptor for some class has been
- * lookuped. Higher usage count means that some class is
- * more frequently being used.
- */
- public int getUsageCount() {
- return usageCount;
- }
-
// ---------------------------------------------------------------- special
private final boolean isArray;
@@ -177,6 +163,25 @@ public class ClassDescriptor {
return isCollection;
}
+ private final boolean isSupplier;
+
+ /**
+ * Returns true
if type is a supplier.
+ */
+ public boolean isSupplier() {
+ return isSupplier;
+ }
+
+ private boolean isSystemClass;
+
+ /**
+ * Returns true
is class is a system class and should not
+ * expose fields or declared methods.
+ */
+ public boolean isSystemClass() {
+ return isSystemClass;
+ }
+
// ---------------------------------------------------------------- fields
private Fields fields;
@@ -195,8 +200,8 @@ public class ClassDescriptor {
/**
* Returns field descriptor.
*/
- public FieldDescriptor getFieldDescriptor(String name, boolean declared) {
- FieldDescriptor fieldDescriptor = getFields().getFieldDescriptor(name);
+ public FieldDescriptor getFieldDescriptor(final String name, final boolean declared) {
+ final FieldDescriptor fieldDescriptor = getFields().getFieldDescriptor(name);
if (fieldDescriptor != null) {
if (!fieldDescriptor.matchDeclared(declared)) {
@@ -232,8 +237,8 @@ public class ClassDescriptor {
/**
* Returns {@link MethodDescriptor method descriptor} identified by name and parameters.
*/
- public MethodDescriptor getMethodDescriptor(String name, boolean declared) {
- MethodDescriptor methodDescriptor = getMethods().getMethodDescriptor(name);
+ public MethodDescriptor getMethodDescriptor(final String name, final boolean declared) {
+ final MethodDescriptor methodDescriptor = getMethods().getMethodDescriptor(name);
if ((methodDescriptor != null) && methodDescriptor.matchDeclared(declared)) {
return methodDescriptor;
@@ -246,8 +251,8 @@ public class ClassDescriptor {
/**
* Returns {@link MethodDescriptor method descriptor} identified by name and parameters.
*/
- public MethodDescriptor getMethodDescriptor(String name, Class[] params, boolean declared) {
- MethodDescriptor methodDescriptor = getMethods().getMethodDescriptor(name, params);
+ public MethodDescriptor getMethodDescriptor(final String name, final Class[] params, final boolean declared) {
+ final MethodDescriptor methodDescriptor = getMethods().getMethodDescriptor(name, params);
if ((methodDescriptor != null) && methodDescriptor.matchDeclared(declared)) {
return methodDescriptor;
@@ -259,7 +264,7 @@ public class ClassDescriptor {
/**
* Returns an array of all methods with the same name.
*/
- public MethodDescriptor[] getAllMethodDescriptors(String name) {
+ public MethodDescriptor[] getAllMethodDescriptors(final String name) {
return getMethods().getAllMethodDescriptors(name);
}
@@ -289,7 +294,7 @@ public class ClassDescriptor {
* Returns property descriptor. Declared flag is matched on both read and write
* methods.
*/
- public PropertyDescriptor getPropertyDescriptor(String name, boolean declared) {
+ public PropertyDescriptor getPropertyDescriptor(final String name, final boolean declared) {
PropertyDescriptor propertyDescriptor = getProperties().getPropertyDescriptor(name);
if ((propertyDescriptor != null) && propertyDescriptor.matchDeclared(declared)) {
@@ -324,7 +329,7 @@ public class ClassDescriptor {
/**
* Returns the default ctor or null
if not found.
*/
- public CtorDescriptor getDefaultCtorDescriptor(boolean declared) {
+ public CtorDescriptor getDefaultCtorDescriptor(final boolean declared) {
CtorDescriptor defaultCtor = getCtors().getDefaultCtor();
if ((defaultCtor != null) && defaultCtor.matchDeclared(declared)) {
@@ -336,7 +341,7 @@ public class ClassDescriptor {
/**
* Returns the constructor identified by arguments or null
if not found.
*/
- public CtorDescriptor getCtorDescriptor(Class[] args, boolean declared) {
+ public CtorDescriptor getCtorDescriptor(final Class[] args, final boolean declared) {
CtorDescriptor ctorDescriptor = getCtors().getCtorDescriptor(args);
if ((ctorDescriptor != null) && ctorDescriptor.matchDeclared(declared)) {
diff --git a/fine-jodd/src/main/java/com/fr/third/jodd/introspector/ClassIntrospector.java b/fine-jodd/src/main/java/com/fr/third/jodd/introspector/ClassIntrospector.java
index 604e54707..8885fa872 100644
--- a/fine-jodd/src/main/java/com/fr/third/jodd/introspector/ClassIntrospector.java
+++ b/fine-jodd/src/main/java/com/fr/third/jodd/introspector/ClassIntrospector.java
@@ -26,31 +26,41 @@
package com.fr.third.jodd.introspector;
+import java.util.Objects;
+
/**
- * Default class {@link Introspector} simply delegates method calls for
+ * Default class {@link ClassIntrospector} simply delegates method calls for
* more convenient usage.
*/
-public class ClassIntrospector {
+public interface ClassIntrospector {
+
+ class Implementation {
+ private static ClassIntrospector classIntrospector = new CachingIntrospector();
+
+ /**
+ * Sets default implementation.
+ */
+ public static void set(final ClassIntrospector classIntrospector) {
+ Objects.requireNonNull(classIntrospector);
+ Implementation.classIntrospector = classIntrospector;
+ }
+ }
/**
- * Returns class descriptor for specified type.
+ * Returns default implementation.
*/
- public static ClassDescriptor lookup(Class type) {
- return JoddIntrospector.introspector.lookup(type);
+ static ClassIntrospector get() {
+ return Implementation.classIntrospector;
}
/**
- * Registers new type.
+ * Returns class descriptor for specified type.
*/
- public static ClassDescriptor register(Class type) {
- return JoddIntrospector.introspector.register(type);
- }
+ ClassDescriptor lookup(Class type);
/**
* Clears all cached data.
*/
- public static void reset() {
- JoddIntrospector.introspector.reset();
- }
+ void reset();
}
\ No newline at end of file
diff --git a/fine-jodd/src/main/java/com/fr/third/jodd/introspector/CtorDescriptor.java b/fine-jodd/src/main/java/com/fr/third/jodd/introspector/CtorDescriptor.java
index 3c60bde84..cea1a4cc7 100644
--- a/fine-jodd/src/main/java/com/fr/third/jodd/introspector/CtorDescriptor.java
+++ b/fine-jodd/src/main/java/com/fr/third/jodd/introspector/CtorDescriptor.java
@@ -25,8 +25,7 @@
package com.fr.third.jodd.introspector;
-import com.fr.third.jodd.util.ReflectUtil;
-import com.fr.third.jodd.util.ReflectUtil;
+import com.fr.third.jodd.util.ClassUtil;
import java.lang.reflect.Constructor;
@@ -38,12 +37,12 @@ public class CtorDescriptor extends Descriptor {
protected final Constructor constructor;
protected final Class[] parameters;
- public CtorDescriptor(ClassDescriptor classDescriptor, Constructor constructor) {
- super(classDescriptor, ReflectUtil.isPublic(constructor));
+ public CtorDescriptor(final ClassDescriptor classDescriptor, final Constructor constructor) {
+ super(classDescriptor, ClassUtil.isPublic(constructor));
this.constructor = constructor;
this.parameters = constructor.getParameterTypes();
- ReflectUtil.forceAccess(constructor);
+ ClassUtil.forceAccess(constructor);
}
/**
diff --git a/fine-jodd/src/main/java/com/fr/third/jodd/introspector/Ctors.java b/fine-jodd/src/main/java/com/fr/third/jodd/introspector/Ctors.java
index d7fc4f837..a48a13734 100644
--- a/fine-jodd/src/main/java/com/fr/third/jodd/introspector/Ctors.java
+++ b/fine-jodd/src/main/java/com/fr/third/jodd/introspector/Ctors.java
@@ -36,7 +36,7 @@ public class Ctors {
protected final CtorDescriptor[] allCtors;
protected CtorDescriptor defaultCtor;
- public Ctors(ClassDescriptor classDescriptor) {
+ public Ctors(final ClassDescriptor classDescriptor) {
this.classDescriptor = classDescriptor;
this.allCtors = inspectConstructors();
}
@@ -67,7 +67,7 @@ public class Ctors {
/**
* Creates new {@link CtorDescriptor}.
*/
- protected CtorDescriptor createCtorDescriptor(Constructor ctor) {
+ protected CtorDescriptor createCtorDescriptor(final Constructor ctor) {
return new CtorDescriptor(classDescriptor, ctor);
}
@@ -83,7 +83,7 @@ public class Ctors {
/**
* Finds constructor description that matches given argument types.
*/
- public CtorDescriptor getCtorDescriptor(Class... args) {
+ public CtorDescriptor getCtorDescriptor(final Class... args) {
ctors:
for (CtorDescriptor ctorDescriptor : allCtors) {
Class[] arg = ctorDescriptor.getParameters();
diff --git a/fine-jodd/src/main/java/com/fr/third/jodd/introspector/Descriptor.java b/fine-jodd/src/main/java/com/fr/third/jodd/introspector/Descriptor.java
index 0145b0a21..f8d79da0d 100644
--- a/fine-jodd/src/main/java/com/fr/third/jodd/introspector/Descriptor.java
+++ b/fine-jodd/src/main/java/com/fr/third/jodd/introspector/Descriptor.java
@@ -33,7 +33,7 @@ public abstract class Descriptor {
protected final ClassDescriptor classDescriptor;
protected final boolean isPublic;
- protected Descriptor(ClassDescriptor classDescriptor, boolean isPublic) {
+ protected Descriptor(final ClassDescriptor classDescriptor, final boolean isPublic) {
this.classDescriptor = classDescriptor;
this.isPublic = isPublic;
}
@@ -55,7 +55,7 @@ public abstract class Descriptor {
/**
* Returns true
if descriptor content matches required declared flag.
*/
- public boolean matchDeclared(boolean declared) {
+ public boolean matchDeclared(final boolean declared) {
if (!declared) {
return isPublic;
}
diff --git a/fine-jodd/src/main/java/com/fr/third/jodd/introspector/FieldDescriptor.java b/fine-jodd/src/main/java/com/fr/third/jodd/introspector/FieldDescriptor.java
index 7692ff42d..7388726b7 100644
--- a/fine-jodd/src/main/java/com/fr/third/jodd/introspector/FieldDescriptor.java
+++ b/fine-jodd/src/main/java/com/fr/third/jodd/introspector/FieldDescriptor.java
@@ -25,36 +25,37 @@
package com.fr.third.jodd.introspector;
-import com.fr.third.jodd.util.ReflectUtil;
-import com.fr.third.jodd.util.ReflectUtil;
+import com.fr.third.jodd.util.ClassUtil;
import java.lang.reflect.Field;
-import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Type;
/**
* Field descriptor. Holds additional field data,
* that might be specific to implementation class.
*/
-public class FieldDescriptor extends Descriptor implements Getter, Setter {
+public class FieldDescriptor extends Descriptor {
+
+ public static final FieldDescriptor[] EMPTY_ARRAY = new FieldDescriptor[0];
protected final Field field;
protected final Type type;
protected final Class rawType;
protected final Class rawComponentType;
protected final Class rawKeyComponentType;
+ protected final MapperFunction mapperFunction;
/**
* Creates new field descriptor and resolve all additional field data.
* Also, forces access to a field.
*/
- public FieldDescriptor(ClassDescriptor classDescriptor, Field field) {
- super(classDescriptor, ReflectUtil.isPublic(field));
+ public FieldDescriptor(final ClassDescriptor classDescriptor, final Field field) {
+ super(classDescriptor, ClassUtil.isPublic(field));
this.field = field;
this.type = field.getGenericType();
- this.rawType = ReflectUtil.getRawType(type, classDescriptor.getType());
+ this.rawType = ClassUtil.getRawType(type, classDescriptor.getType());
- Class[] componentTypes = ReflectUtil.getComponentTypes(type, classDescriptor.getType());
+ final Class[] componentTypes = ClassUtil.getComponentTypes(type, classDescriptor.getType());
if (componentTypes != null) {
this.rawComponentType = componentTypes[componentTypes.length - 1];
this.rawKeyComponentType = componentTypes[0];
@@ -63,7 +64,19 @@ public class FieldDescriptor extends Descriptor implements Getter, Setter {
this.rawKeyComponentType = null;
}
- ReflectUtil.forceAccess(field);
+ // force access
+
+ ClassUtil.forceAccess(field);
+
+ // mapper
+
+ final Mapper mapper = field.getAnnotation(Mapper.class);
+
+ if (mapper != null) {
+ mapperFunction = MapperFunctionInstances.get().lookup(mapper.value());
+ } else {
+ mapperFunction = null;
+ }
}
/**
@@ -108,37 +121,7 @@ public class FieldDescriptor extends Descriptor implements Getter, Setter {
* Resolves raw component type for given index. This value is NOT cached.
*/
public Class[] resolveRawComponentTypes() {
- return ReflectUtil.getComponentTypes(type, classDescriptor.getType());
- }
-
- // ---------------------------------------------------------------- getter/setter
-
- public Object invokeGetter(Object target) throws InvocationTargetException, IllegalAccessException {
- return field.get(target);
- }
-
- public Class getGetterRawType() {
- return getRawType();
- }
-
- public Class getGetterRawComponentType() {
- return getRawComponentType();
- }
-
- public Class getGetterRawKeyComponentType() {
- return getRawKeyComponentType();
- }
-
- public void invokeSetter(Object target, Object argument) throws IllegalAccessException {
- field.set(target, argument);
- }
-
- public Class getSetterRawType() {
- return getRawType();
- }
-
- public Class getSetterRawComponentType() {
- return getRawComponentType();
+ return ClassUtil.getComponentTypes(type, classDescriptor.getType());
}
// ---------------------------------------------------------------- toString
diff --git a/fine-jodd/src/main/java/com/fr/third/jodd/introspector/Fields.java b/fine-jodd/src/main/java/com/fr/third/jodd/introspector/Fields.java
index 416b6ca70..33a1cc876 100644
--- a/fine-jodd/src/main/java/com/fr/third/jodd/introspector/Fields.java
+++ b/fine-jodd/src/main/java/com/fr/third/jodd/introspector/Fields.java
@@ -25,13 +25,14 @@
package com.fr.third.jodd.introspector;
-import com.fr.third.jodd.util.ReflectUtil;
-import com.fr.third.jodd.util.ReflectUtil;
+import com.fr.third.jodd.util.ClassUtil;
import java.lang.reflect.Field;
import java.util.Arrays;
+import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
+import java.util.Map;
/**
* Collection of {@link FieldDescriptor field descriptors}.
@@ -39,7 +40,7 @@ import java.util.HashMap;
public class Fields {
protected final ClassDescriptor classDescriptor;
- protected final HashMap fieldsMap;
+ protected final Map fieldsMap;
// cache
private FieldDescriptor[] allFields;
@@ -47,7 +48,7 @@ public class Fields {
/**
* Creates new fields collection.
*/
- public Fields(ClassDescriptor classDescriptor) {
+ public Fields(final ClassDescriptor classDescriptor) {
this.classDescriptor = classDescriptor;
this.fieldsMap = inspectFields();
}
@@ -55,16 +56,19 @@ public class Fields {
/**
* Inspects fields and returns map of {@link FieldDescriptor field descriptors}.
*/
- protected HashMap inspectFields() {
- boolean scanAccessible = classDescriptor.isScanAccessible();
- Class type = classDescriptor.getType();
+ private Map inspectFields() {
+ if (classDescriptor.isSystemClass()) {
+ return emptyFields();
+ }
+ final boolean scanAccessible = classDescriptor.isScanAccessible();
+ final Class type = classDescriptor.getType();
- Field[] fields = scanAccessible ? ReflectUtil.getAccessibleFields(type) : ReflectUtil.getSupportedFields(type);
+ final Field[] fields = scanAccessible ? ClassUtil.getAccessibleFields(type) : ClassUtil.getSupportedFields(type);
- HashMap map = new HashMap(fields.length);
+ final HashMap map = new HashMap<>(fields.length);
- for (Field field : fields) {
- String fieldName = field.getName();
+ for (final Field field : fields) {
+ final String fieldName = field.getName();
if (fieldName.equals("serialVersionUID")) {
continue;
@@ -76,10 +80,18 @@ public class Fields {
return map;
}
+ /**
+ * Defines empty fields for special cases.
+ */
+ private Map emptyFields() {
+ allFields = FieldDescriptor.EMPTY_ARRAY;
+ return Collections.emptyMap();
+ }
+
/**
* Creates new {@code FieldDescriptor}.
*/
- protected FieldDescriptor createFieldDescriptor(Field field) {
+ protected FieldDescriptor createFieldDescriptor(final Field field) {
return new FieldDescriptor(classDescriptor, field);
}
@@ -90,7 +102,7 @@ public class Fields {
* Returns {@link FieldDescriptor field descriptor} for given field name
* or null
if field does not exist.
*/
- public FieldDescriptor getFieldDescriptor(String name) {
+ public FieldDescriptor getFieldDescriptor(final String name) {
return fieldsMap.get(name);
}
@@ -108,11 +120,7 @@ public class Fields {
index++;
}
- Arrays.sort(allFields, new Comparator() {
- public int compare(FieldDescriptor fd1, FieldDescriptor fd2) {
- return fd1.getField().getName().compareTo(fd2.getField().getName());
- }
- });
+ Arrays.sort(allFields, Comparator.comparing(fd -> fd.getField().getName()));
this.allFields = allFields;
}
diff --git a/fine-jodd/src/main/java/com/fr/third/jodd/introspector/Getter.java b/fine-jodd/src/main/java/com/fr/third/jodd/introspector/Getter.java
index cc8b1acfe..2c62afc99 100644
--- a/fine-jodd/src/main/java/com/fr/third/jodd/introspector/Getter.java
+++ b/fine-jodd/src/main/java/com/fr/third/jodd/introspector/Getter.java
@@ -32,6 +32,57 @@ import java.lang.reflect.InvocationTargetException;
*/
public interface Getter {
+ static Getter of(final MethodDescriptor methodDescriptor) {
+
+ return new Getter() {
+
+ @Override
+ public Object invokeGetter(final Object target) throws InvocationTargetException, IllegalAccessException {
+ return methodDescriptor.method.invoke(target);
+ }
+
+ @Override
+ public Class getGetterRawType() {
+ return methodDescriptor.getRawReturnType();
+ }
+
+ @Override
+ public Class getGetterRawComponentType() {
+ return methodDescriptor.getRawReturnComponentType();
+ }
+
+ @Override
+ public Class getGetterRawKeyComponentType() {
+ return methodDescriptor.getRawReturnKeyComponentType();
+ }
+ };
+ }
+
+ static Getter of(final FieldDescriptor fieldDescriptor) {
+ return new Getter() {
+
+ @Override
+ public Object invokeGetter(final Object target) throws IllegalAccessException {
+ return fieldDescriptor.field.get(target);
+ }
+
+ @Override
+ public Class getGetterRawType() {
+ return fieldDescriptor.getRawType();
+ }
+
+ @Override
+ public Class getGetterRawComponentType() {
+ return fieldDescriptor.getRawComponentType();
+ }
+
+ @Override
+ public Class getGetterRawKeyComponentType() {
+ return fieldDescriptor.getRawKeyComponentType();
+ }
+ };
+ }
+
Object invokeGetter(Object target) throws InvocationTargetException, IllegalAccessException;
Class getGetterRawType();
diff --git a/fine-jodd/src/main/java/com/fr/third/jodd/introspector/JoddIntrospector.java b/fine-jodd/src/main/java/com/fr/third/jodd/introspector/Mapper.java
similarity index 75%
rename from fine-jodd/src/main/java/com/fr/third/jodd/introspector/JoddIntrospector.java
rename to fine-jodd/src/main/java/com/fr/third/jodd/introspector/Mapper.java
index 713e40056..27c5c477b 100644
--- a/fine-jodd/src/main/java/com/fr/third/jodd/introspector/JoddIntrospector.java
+++ b/fine-jodd/src/main/java/com/fr/third/jodd/introspector/Mapper.java
@@ -25,24 +25,19 @@
package com.fr.third.jodd.introspector;
-import com.fr.third.jodd.Jodd;
-import com.fr.third.jodd.Jodd;
-
-public class JoddIntrospector {
-
- /**
- * Default {@link Introspector} implementation.
- */
- public static Introspector introspector = new CachingIntrospector();
-
- // ---------------------------------------------------------------- module
-
- static {
- init();
- }
-
- public static void init() {
- Jodd.init(JoddIntrospector.class);
- }
-
-}
\ No newline at end of file
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Value or type mapper.
+ * @see MapperFunction
+ */
+@Documented
+@Retention(value = RetentionPolicy.RUNTIME)
+@Target({ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER})
+public @interface Mapper {
+ Class extends MapperFunction> value();
+}
diff --git a/fine-jodd/src/main/java/com/fr/third/jodd/introspector/MapperFunction.java b/fine-jodd/src/main/java/com/fr/third/jodd/introspector/MapperFunction.java
new file mode 100644
index 000000000..436473bcf
--- /dev/null
+++ b/fine-jodd/src/main/java/com/fr/third/jodd/introspector/MapperFunction.java
@@ -0,0 +1,37 @@
+// Copyright (c) 2003-present, Jodd Team (http://jodd.org)
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+//
+// 1. Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+// POSSIBILITY OF SUCH DAMAGE.
+
+package com.fr.third.jodd.introspector;
+
+import java.util.function.Function;
+
+/**
+ * Mapper function allows object to be converted before actually used - usually before injected using
+ * {@link com.fr.third.jodd.bean.BeanUtil}.
+ */
+@FunctionalInterface
+public interface MapperFunction extends Function {
+
+}
diff --git a/fine-jodd/src/main/java/com/fr/third/jodd/introspector/MapperFunctionInstances.java b/fine-jodd/src/main/java/com/fr/third/jodd/introspector/MapperFunctionInstances.java
new file mode 100644
index 000000000..06ad30946
--- /dev/null
+++ b/fine-jodd/src/main/java/com/fr/third/jodd/introspector/MapperFunctionInstances.java
@@ -0,0 +1,57 @@
+// Copyright (c) 2003-present, Jodd Team (http://jodd.org)
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+//
+// 1. Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+// POSSIBILITY OF SUCH DAMAGE.
+
+package com.fr.third.jodd.introspector;
+
+import com.fr.third.jodd.cache.TypeCache;
+import com.fr.third.jodd.util.ClassUtil;
+
+/**
+ * Simple cache of {@link MapperFunction} instances.
+ */
+public class MapperFunctionInstances {
+
+ private static final MapperFunctionInstances MAPPER_FUNCTION_INSTANCES = new MapperFunctionInstances();
+
+ /**
+ * Returns the instance.
+ */
+ public static MapperFunctionInstances get() {
+ return MAPPER_FUNCTION_INSTANCES;
+ }
+
+ protected TypeCache typeCache = TypeCache.createDefault();
+
+ public MapperFunction lookup(final Class extends MapperFunction> mapperFunctionClass) {
+ return typeCache.get(mapperFunctionClass, (c) -> {
+ try {
+ return ClassUtil.newInstance(mapperFunctionClass);
+ } catch (final Exception ex) {
+ throw new IllegalArgumentException("Invalid mapper class " + c, ex);
+ }
+ });
+ }
+
+}
diff --git a/fine-jodd/src/main/java/com/fr/third/jodd/introspector/MethodDescriptor.java b/fine-jodd/src/main/java/com/fr/third/jodd/introspector/MethodDescriptor.java
index 974e5b0e2..4b45abbff 100644
--- a/fine-jodd/src/main/java/com/fr/third/jodd/introspector/MethodDescriptor.java
+++ b/fine-jodd/src/main/java/com/fr/third/jodd/introspector/MethodDescriptor.java
@@ -25,10 +25,8 @@
package com.fr.third.jodd.introspector;
-import com.fr.third.jodd.util.ReflectUtil;
-import com.fr.third.jodd.util.ReflectUtil;
+import com.fr.third.jodd.util.ClassUtil;
-import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Type;
@@ -36,23 +34,27 @@ import java.lang.reflect.Type;
* Method descriptor. Holds additional method data,
* that might be specific to implementation class.
*/
-public class MethodDescriptor extends Descriptor implements Getter, Setter {
+public class MethodDescriptor extends Descriptor {
+
+ private static final MethodParamDescriptor[] NO_PARAMS = new MethodParamDescriptor[0];
protected final Method method;
protected final Type returnType;
protected final Class rawReturnType;
protected final Class rawReturnComponentType;
protected final Class rawReturnKeyComponentType;
- protected final Class[] rawParameterTypes;
- protected final Class[] rawParameterComponentTypes;
+ protected final MethodParamDescriptor[] parameters;
+ protected final MapperFunction mapperFunction;
+
+// protected final Function getterFunction;
- public MethodDescriptor(ClassDescriptor classDescriptor, Method method) {
- super(classDescriptor, ReflectUtil.isPublic(method));
+ public MethodDescriptor(final ClassDescriptor classDescriptor, final Method method) {
+ super(classDescriptor, ClassUtil.isPublic(method));
this.method = method;
this.returnType = method.getGenericReturnType();
- this.rawReturnType = ReflectUtil.getRawType(returnType, classDescriptor.getType());
+ this.rawReturnType = ClassUtil.getRawType(returnType, classDescriptor.getType());
- Class[] componentTypes = ReflectUtil.getComponentTypes(returnType, classDescriptor.getType());
+ final Class[] componentTypes = ClassUtil.getComponentTypes(returnType, classDescriptor.getType());
if (componentTypes != null) {
this.rawReturnComponentType = componentTypes[componentTypes.length - 1];
this.rawReturnKeyComponentType = componentTypes[0];
@@ -61,26 +63,68 @@ public class MethodDescriptor extends Descriptor implements Getter, Setter {
this.rawReturnKeyComponentType = null;
}
- ReflectUtil.forceAccess(method);
+ // force access
+
+ ClassUtil.forceAccess(method);
+
+ // mapper
- Type[] params = method.getGenericParameterTypes();
- Type[] genericParams = method.getGenericParameterTypes();
+ final Mapper mapper = method.getAnnotation(Mapper.class);
+
+ if (mapper != null) {
+ mapperFunction = MapperFunctionInstances.get().lookup(mapper.value());
+ } else {
+ mapperFunction = null;
+ }
- rawParameterTypes = new Class[params.length];
- rawParameterComponentTypes = genericParams.length == 0 ? null : new Class[params.length];
+ // parameters
- for (int i = 0; i < params.length; i++) {
- Type type = params[i];
- rawParameterTypes[i] = ReflectUtil.getRawType(type, classDescriptor.getType());
- if (rawParameterComponentTypes != null) {
- rawParameterComponentTypes[i] = ReflectUtil.getComponentType(genericParams[i], classDescriptor.getType(), -1);
+ if (method.getParameterCount() == 0) {
+ parameters = NO_PARAMS;
+ }
+ else {
+ parameters = new MethodParamDescriptor[method.getParameterCount()];
+
+ Class[] params = method.getParameterTypes();
+ Type[] genericParams = method.getGenericParameterTypes();
+
+ for (int i = 0; i < params.length; i++) {
+ final Class parameterType = params[i];
+ final Class rawParameterType = genericParams.length == 0 ?
+ parameterType :
+ ClassUtil.getRawType(genericParams[i], classDescriptor.getType());
+ final Class rawParameterComponentType = genericParams.length == 0 ?
+ null :
+ ClassUtil.getComponentType(genericParams[i], classDescriptor.getType(), -1);
+
+ parameters[i] = new MethodParamDescriptor(parameterType, rawParameterType, rawParameterComponentType);
}
}
+
+// try {
+// MethodHandles.Lookup lookup = MethodHandles.lookup();
+// CallSite callSite = LambdaMetafactory.metafactory(lookup,
+// "apply",
+// MethodType.methodType(Function.class),
+// MethodType.methodType(Object.class, Object.class),
+// lookup.findVirtual(
+// classDescriptor.getType(),
+// method.getName(),
+// MethodType.methodType(method.getReturnType())),
+// MethodType.methodType(method.getReturnType(), classDescriptor.type)
+// );
+//
+// this.getterFunction = (Function) callSite.getTarget().invokeExact();
+// }
+// catch (Throwable ex) {
+// throw new IllegalArgumentException(ex);
+// }
}
/**
* Returns method name.
*/
+ @Override
public String getName() {
return method.getName();
}
@@ -122,56 +166,21 @@ public class MethodDescriptor extends Descriptor implements Getter, Setter {
* This value is NOT cached.
*/
public Class[] resolveRawReturnComponentTypes() {
- return ReflectUtil.getComponentTypes(returnType, classDescriptor.getType());
+ return ClassUtil.getComponentTypes(returnType, classDescriptor.getType());
}
/**
- * Returns raw parameter types.
+ * Returns {@link MethodParamDescriptor method parameteres}.
*/
- public Class[] getRawParameterTypes() {
- return rawParameterTypes;
+ public MethodParamDescriptor[] getParameters() {
+ return parameters;
}
/**
- * Returns raw parameter component types. Returns null
- * if data does not exist.
+ * Returns number of parameters.
*/
- public Class[] getRawParameterComponentTypes() {
- return rawParameterComponentTypes;
- }
-
- // ---------------------------------------------------------------- getter/setter
-
- public Object invokeGetter(Object target) throws InvocationTargetException, IllegalAccessException {
- return method.invoke(target, null);
- }
-
- public Class getGetterRawType() {
- return getRawReturnType();
- }
-
- public Class getGetterRawComponentType() {
- return getRawReturnComponentType();
- }
-
- public Class getGetterRawKeyComponentType() {
- return getRawReturnKeyComponentType();
- }
-
- public void invokeSetter(Object target, Object argument) throws IllegalAccessException, InvocationTargetException {
- method.invoke(target, argument);
- }
-
- public Class getSetterRawType() {
- return getRawParameterTypes()[0];
- }
-
- public Class getSetterRawComponentType() {
- Class[] ts = getRawParameterComponentTypes();
- if (ts == null) {
- return null;
- }
- return ts[0];
+ public int getParameterCount() {
+ return parameters.length;
}
// ---------------------------------------------------------------- toString
diff --git a/fine-jodd/src/main/java/com/fr/third/jodd/introspector/Introspector.java b/fine-jodd/src/main/java/com/fr/third/jodd/introspector/MethodParamDescriptor.java
similarity index 71%
rename from fine-jodd/src/main/java/com/fr/third/jodd/introspector/Introspector.java
rename to fine-jodd/src/main/java/com/fr/third/jodd/introspector/MethodParamDescriptor.java
index 9f563e6e8..7ee278c52 100644
--- a/fine-jodd/src/main/java/com/fr/third/jodd/introspector/Introspector.java
+++ b/fine-jodd/src/main/java/com/fr/third/jodd/introspector/MethodParamDescriptor.java
@@ -25,27 +25,29 @@
package com.fr.third.jodd.introspector;
-
/**
- * Provides introspection analysis against any java class.
- * Implementations may cache {@link ClassDescriptor} objects to improve performance.
- * @see CachingIntrospector
+ * Method parameter descriptor.
*/
-public interface Introspector {
- /**
- * Returns the {@link ClassDescriptor} object for specified class.
- */
- ClassDescriptor lookup(Class type);
+public class MethodParamDescriptor {
+ protected final Class type;
+ protected final Class rawType;
+ protected final Class rawComponentType;
+
+ public MethodParamDescriptor(final Class parameterType, final Class rawParameterType, final Class rawParameterComponentType) {
+ this.type = parameterType;
+ this.rawType = rawParameterType;
+ this.rawComponentType = rawParameterComponentType;
+ }
- /**
- * Registers new class type. If type already registered, it will be
- * reset and registered again with new class descriptor.
- */
- ClassDescriptor register(Class type);
+ public Class getType() {
+ return type;
+ }
- /**
- * Resets current cache.
- */
- void reset();
+ public Class getRawType() {
+ return rawType;
+ }
+ public Class getRawComponentType() {
+ return rawComponentType;
+ }
}
diff --git a/fine-jodd/src/main/java/com/fr/third/jodd/introspector/Methods.java b/fine-jodd/src/main/java/com/fr/third/jodd/introspector/Methods.java
index efefef68b..75e8e267d 100644
--- a/fine-jodd/src/main/java/com/fr/third/jodd/introspector/Methods.java
+++ b/fine-jodd/src/main/java/com/fr/third/jodd/introspector/Methods.java
@@ -26,9 +26,7 @@
package com.fr.third.jodd.introspector;
import com.fr.third.jodd.util.ArraysUtil;
-import com.fr.third.jodd.util.ReflectUtil;
-import com.fr.third.jodd.util.ArraysUtil;
-import com.fr.third.jodd.util.ReflectUtil;
+import com.fr.third.jodd.util.ClassUtil;
import java.lang.reflect.Method;
import java.util.ArrayList;
@@ -49,7 +47,7 @@ public class Methods {
// cache
private MethodDescriptor[] allMethods;
- public Methods(ClassDescriptor classDescriptor) {
+ public Methods(final ClassDescriptor classDescriptor) {
this.classDescriptor = classDescriptor;
this.methodsMap = inspectMethods();
}
@@ -59,14 +57,19 @@ public class Methods {
*/
protected HashMap inspectMethods() {
boolean scanAccessible = classDescriptor.isScanAccessible();
- Class type = classDescriptor.getType();
- Method[] methods = scanAccessible ? ReflectUtil.getAccessibleMethods(type) : ReflectUtil.getSupportedMethods(type);
+ if (classDescriptor.isSystemClass()) {
+ scanAccessible = false;
+ }
+
+ final Class type = classDescriptor.getType();
+
+ final Method[] methods = scanAccessible ? ClassUtil.getAccessibleMethods(type) : ClassUtil.getSupportedMethods(type);
- HashMap map = new HashMap(methods.length);
+ final HashMap map = new HashMap<>(methods.length);
- for (Method method : methods) {
- String methodName = method.getName();
+ for (final Method method : methods) {
+ final String methodName = method.getName();
MethodDescriptor[] mds = map.get(methodName);
@@ -87,7 +90,7 @@ public class Methods {
/**
* Creates new {@code MethodDescriptor}.
*/
- protected MethodDescriptor createMethodDescriptor(Method method) {
+ protected MethodDescriptor createMethodDescriptor(final Method method) {
return new MethodDescriptor(classDescriptor, method);
}
@@ -98,14 +101,14 @@ public class Methods {
* Returns a method that matches given name and parameter types.
* Returns null
if method is not found.
*/
- public MethodDescriptor getMethodDescriptor(String name, Class[] paramTypes) {
- MethodDescriptor[] methodDescriptors = methodsMap.get(name);
+ public MethodDescriptor getMethodDescriptor(final String name, final Class[] paramTypes) {
+ final MethodDescriptor[] methodDescriptors = methodsMap.get(name);
if (methodDescriptors == null) {
return null;
}
for (MethodDescriptor methodDescriptor : methodDescriptors) {
- Method m = methodDescriptor.getMethod();
- if (ReflectUtil.compareParameters(m.getParameterTypes(), paramTypes)) {
+ final Method m = methodDescriptor.getMethod();
+ if (ClassUtil.compareParameters(m.getParameterTypes(), paramTypes)) {
return methodDescriptor;
}
}
@@ -118,8 +121,8 @@ public class Methods {
* Returns null
if no method exist in this collection by given name.
* @see #getMethodDescriptor(String, Class[])
*/
- public MethodDescriptor getMethodDescriptor(String name) {
- MethodDescriptor[] methodDescriptors = methodsMap.get(name);
+ public MethodDescriptor getMethodDescriptor(final String name) {
+ final MethodDescriptor[] methodDescriptors = methodsMap.get(name);
if (methodDescriptors == null) {
return null;
}
@@ -132,7 +135,7 @@ public class Methods {
/**
* Returns all methods for given name. Returns null
if method not found.
*/
- public MethodDescriptor[] getAllMethodDescriptors(String name) {
+ public MethodDescriptor[] getAllMethodDescriptors(final String name) {
return methodsMap.get(name);
}
@@ -141,19 +144,15 @@ public class Methods {
*/
public MethodDescriptor[] getAllMethodDescriptors() {
if (allMethods == null) {
- List allMethodsList = new ArrayList();
+ final List allMethodsList = new ArrayList<>();
for (MethodDescriptor[] methodDescriptors : methodsMap.values()) {
Collections.addAll(allMethodsList, methodDescriptors);
}
- MethodDescriptor[] allMethods = allMethodsList.toArray(new MethodDescriptor[allMethodsList.size()]);
+ final MethodDescriptor[] allMethods = allMethodsList.toArray(new MethodDescriptor[0]);
- Arrays.sort(allMethods, new Comparator() {
- public int compare(MethodDescriptor md1, MethodDescriptor md2) {
- return md1.getMethod().getName().compareTo(md2.getMethod().getName());
- }
- });
+ Arrays.sort(allMethods, Comparator.comparing(md -> md.getMethod().getName()));
this.allMethods = allMethods;
}
diff --git a/fine-jodd/src/main/java/com/fr/third/jodd/introspector/Properties.java b/fine-jodd/src/main/java/com/fr/third/jodd/introspector/Properties.java
index ed7676eaa..1fbca304f 100644
--- a/fine-jodd/src/main/java/com/fr/third/jodd/introspector/Properties.java
+++ b/fine-jodd/src/main/java/com/fr/third/jodd/introspector/Properties.java
@@ -25,8 +25,7 @@
package com.fr.third.jodd.introspector;
-import com.fr.third.jodd.util.ReflectUtil;
-import com.fr.third.jodd.util.ReflectUtil;
+import com.fr.third.jodd.util.ClassUtil;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
@@ -35,8 +34,8 @@ import java.util.Arrays;
import java.util.Comparator;
import java.util.HashMap;
-import static com.fr.third.jodd.util.ReflectUtil.METHOD_GET_PREFIX;
-import static com.fr.third.jodd.util.ReflectUtil.METHOD_IS_PREFIX;
+import static com.fr.third.jodd.util.ClassUtil.METHOD_GET_PREFIX;
+import static com.fr.third.jodd.util.ClassUtil.METHOD_IS_PREFIX;
/**
* Bean properties collection. Property in Java is defined as a pair of
@@ -52,7 +51,7 @@ public class Properties {
// cache
private PropertyDescriptor[] allProperties;
- public Properties(ClassDescriptor classDescriptor) {
+ public Properties(final ClassDescriptor classDescriptor) {
this.classDescriptor = classDescriptor;
this.propertyDescriptors = inspectProperties();
}
@@ -64,9 +63,9 @@ public class Properties {
boolean scanAccessible = classDescriptor.isScanAccessible();
Class type = classDescriptor.getType();
- HashMap map = new HashMap