PageRenderTime 47ms CodeModel.GetById 22ms RepoModel.GetById 0ms app.codeStats 0ms

/plugins/net.jgsuess.epsilon.log.jul/src/net/jgsuess/epsilon/log/jul/Logger.java

https://gitlab.com/jgsuess/epsilon-jul-log
Java | 368 lines | 223 code | 79 blank | 66 comment | 1 complexity | ff8bd1a81015ab57d7ae86f719619a27 MD5 | raw file
  1. package net.jgsuess.epsilon.log.jul;
  2. import static java.util.Arrays.asList;
  3. import static java.util.Optional.empty;
  4. import static java.util.Optional.of;
  5. import static java.util.Set.of;
  6. import static java.util.stream.Collectors.joining;
  7. import static java.util.stream.Collectors.toUnmodifiableSet;
  8. import static java.util.stream.StreamSupport.stream;
  9. import java.net.URI;
  10. import java.nio.file.Path;
  11. import java.util.HashMap;
  12. import java.util.List;
  13. import java.util.Map;
  14. import java.util.Optional;
  15. import java.util.ResourceBundle;
  16. import java.util.Set;
  17. import java.util.function.BiFunction;
  18. import java.util.function.Function;
  19. import java.util.function.Predicate;
  20. import java.util.function.Supplier;
  21. import java.util.logging.Level;
  22. import java.util.logging.LogRecord;
  23. import org.eclipse.epsilon.common.module.IModule;
  24. import org.eclipse.epsilon.eol.execute.context.IEolContext;
  25. import org.eclipse.epsilon.eol.tools.ITool;
  26. import lombok.Getter;
  27. import lombok.Setter;
  28. import lombok.ToString;
  29. @ToString
  30. public final class Logger implements ITool {
  31. @Setter
  32. @Getter
  33. private IEolContext context;
  34. @Setter
  35. @Getter
  36. private Map<String, Function<String, Path>> schemeToLoggerNameComputers = new HashMap<>();
  37. @Setter
  38. @Getter
  39. private Set<Function<URI, Optional<String>>> uriToSourceClassNameMappers;
  40. EolLogger delegate;
  41. public Logger() {
  42. setUriToSourceClassNameMappers(DEFAULT_URI_TO_SOURCE_CLASS_NAME_MAPPERS);
  43. }
  44. @Override
  45. /**
  46. * TODO: Should this be an avenue of configuration for the Logger? What is most
  47. * useful and idiomatic?
  48. */
  49. public void initialize(List<Object> parameters) {
  50. // TODO: What is the resource bundle for this?
  51. final String loggerName = getLoggerName();
  52. final String sourceClassName = getSourceClassName();
  53. delegate = new EolLogger(loggerName, sourceClassName, null);
  54. }
  55. public String getLoggerName() {
  56. /*
  57. * Get the name of the source class
  58. */
  59. final String sourceClassName = getSourceClassName();
  60. /*
  61. * Get function the function that derives the name
  62. */
  63. final String scheme = getModuleUri().getScheme();
  64. /*
  65. * Gets the function for the module URI scheme that applies to mapping this source class
  66. * TODO: Maybe this should also be queried dynamically based on the URI rather than just the scheme.
  67. */
  68. final Function<String, Path> loggerNameComputer = getSchemeToLoggerNameComputers().getOrDefault(scheme, s -> Path.of(""));
  69. /*
  70. * Map the name of the source class to the name of the logger
  71. */
  72. final Path loggerPath = loggerNameComputer.apply(sourceClassName);
  73. /*
  74. * Add dots between components of the logger's name and concatenate
  75. */
  76. final String loggerName = separatePathByDots(loggerPath);
  77. /*
  78. * Return assembled the name
  79. */
  80. return loggerName;
  81. }
  82. public static final String separatePathByDots(final Path path) {
  83. return stream(path.spliterator(), false).map(Path::toString).collect(joining("."));
  84. }
  85. /**
  86. * Get the line where the statement that invoked the statement containing this
  87. * call starts. Intended to provide an implicit means to line-stamp the log
  88. * message.
  89. *
  90. * @return
  91. */
  92. public final int getLine() {
  93. return getContext().getFrameStack().getCurrentStatement().getRegion().getStart().getLine();
  94. }
  95. /**
  96. * Computes the name of the source class based on stored mappings and the module
  97. * uri.
  98. *
  99. * @return
  100. */
  101. public String getSourceClassName() {
  102. final URI uri = getModuleUri();
  103. /**
  104. * Based on the URI, there may be multiple source class names that are produced.
  105. * This can be based on scheme, filename extension or any other factor.
  106. */
  107. final Set<String> uriMappings = URI_TO_NAMES.apply(getUriToSourceClassNameMappers(), uri);
  108. final int numberOfMappings = uriMappings.size();
  109. switch (numberOfMappings) {
  110. case 0:
  111. throw new RuntimeException("No mapping to source class found for URI :" + uri);
  112. case 1:
  113. return uriMappings.iterator().next();
  114. default:
  115. throw new RuntimeException("Ambiguous mapping to source class found for URI :" + uri + " " + uriMappings);
  116. }
  117. }
  118. private URI getModuleUri() {
  119. final IModule module = getModule();
  120. final URI uri = module.getUri();
  121. return uri;
  122. }
  123. /**
  124. * Given a URI scheme name yields a matching predicate for URIs with that
  125. * scheme.
  126. */
  127. public static final Function<String, Predicate<URI>> MATCHES_SCHEME = scheme -> uri -> uri.getScheme()
  128. .matches(scheme);
  129. private static final BiFunction<String, Function<URI, String>, Function<URI, Optional<String>>> IF_SCHEME_FITS = (
  130. scheme,
  131. uriToString) -> uri -> MATCHES_SCHEME.apply(scheme).test(uri) ? of(uriToString.apply(uri)) : empty();
  132. /**
  133. * Maps an Eclipse Platform URI to a String. The String consists of path
  134. * elements starting from index 2 inclusive. So
  135. * <code>platform:/plugin/net.jgsuess.epsilon.log.jul/modules/eol/challenge.eol#something</code>
  136. * yields <code>modules/eol/challenge.eol</code>.
  137. */
  138. public static final Function<URI, Optional<String>> MAP_PLATFORM_URI = IF_SCHEME_FITS.apply("platform",
  139. uri -> getSubPath(3, uri));
  140. /**
  141. * Maps a File URI to a String. The String consists of path elements starting
  142. * from index 0 inclusive. So
  143. * <code>file://some/where/over/the/rainbow.txt</code> yields
  144. * <code>some/where/over/the/rainbow.txt</code>.
  145. */
  146. public static final Function<URI, Optional<String>> MAP_FILE_URI = IF_SCHEME_FITS.apply("file",
  147. uri -> getSubPath(1, uri));
  148. /**
  149. * The set of mapping functions from URI to String this Logger will use by
  150. * default. In this implementation, these are {{@link #MAP_FILE_URI} and
  151. * {@link #MAP_PLATFORM_URI}.
  152. */
  153. public static final Set<Function<URI, Optional<String>>> DEFAULT_URI_TO_SOURCE_CLASS_NAME_MAPPERS = of(
  154. MAP_PLATFORM_URI, MAP_FILE_URI);
  155. /**
  156. * Computes the set of Strings produced by applying a set of mapping functions
  157. * to a URI.
  158. */
  159. public static final BiFunction<Set<Function<URI, Optional<String>>>, URI, Set<String>> URI_TO_NAMES = (
  160. fs, u) -> fs.stream().map(f -> f.apply(u)).filter(Optional::isPresent).map(Optional::get)
  161. .collect(toUnmodifiableSet());
  162. private static final List<String> splitPath(final URI uri) {
  163. final String path = uri.getPath();
  164. return asList(path.split("/"));
  165. }
  166. private static final String getSubPath(final int fromIndex, URI uri) {
  167. return splitPath(uri).subList(fromIndex, splitPath(uri).size()).stream().collect(joining("/"));
  168. }
  169. private IModule getModule() {
  170. return getContext().getModule();
  171. }
  172. public boolean equals(Object obj) {
  173. return delegate.equals(obj);
  174. }
  175. public void log(LogRecord record) {
  176. delegate.log(record);
  177. }
  178. public void log(Level level, String msg) {
  179. delegate.log(level, msg);
  180. }
  181. public void log(Level level, Supplier<String> msgSupplier) {
  182. delegate.log(level, msgSupplier);
  183. }
  184. public void log(Level level, String msg, Object param1) {
  185. delegate.log(level, msg, param1);
  186. }
  187. public void log(Level level, String msg, Object[] params) {
  188. delegate.log(level, msg, params);
  189. }
  190. public void log(Level level, String msg, Throwable thrown) {
  191. delegate.log(level, msg, thrown);
  192. }
  193. public void log(Level level, Throwable thrown, Supplier<String> msgSupplier) {
  194. delegate.log(level, thrown, msgSupplier);
  195. }
  196. public void logp(Level level, String sourceClass, String sourceMethod, String msg) {
  197. delegate.logp(level, sourceClass, sourceMethod, msg);
  198. }
  199. public void logp(Level level, String sourceClass, String sourceMethod, Supplier<String> msgSupplier) {
  200. delegate.logp(level, sourceClass, sourceMethod, msgSupplier);
  201. }
  202. public void logp(Level level, String sourceClass, String sourceMethod, String msg, Object param1) {
  203. delegate.logp(level, sourceClass, sourceMethod, msg, param1);
  204. }
  205. public void logp(Level level, String sourceClass, String sourceMethod, String msg, Object[] params) {
  206. delegate.logp(level, sourceClass, sourceMethod, msg, params);
  207. }
  208. public void logp(Level level, String sourceClass, String sourceMethod, String msg, Throwable thrown) {
  209. delegate.logp(level, sourceClass, sourceMethod, msg, thrown);
  210. }
  211. public void logp(Level level, String sourceClass, String sourceMethod, Throwable thrown,
  212. Supplier<String> msgSupplier) {
  213. delegate.logp(level, sourceClass, sourceMethod, thrown, msgSupplier);
  214. }
  215. public void logrb(Level level, String sourceClass, String sourceMethod, ResourceBundle bundle, String msg,
  216. Object... params) {
  217. delegate.logrb(level, sourceClass, sourceMethod, bundle, msg, params);
  218. }
  219. public void logrb(Level level, ResourceBundle bundle, String msg, Object... params) {
  220. delegate.logrb(level, bundle, msg, params);
  221. }
  222. public void logrb(Level level, String sourceClass, String sourceMethod, ResourceBundle bundle, String msg,
  223. Throwable thrown) {
  224. delegate.logrb(level, sourceClass, sourceMethod, bundle, msg, thrown);
  225. }
  226. public void logrb(Level level, ResourceBundle bundle, String msg, Throwable thrown) {
  227. delegate.logrb(level, bundle, msg, thrown);
  228. }
  229. public void entering(String sourceClass, String sourceMethod) {
  230. delegate.entering(sourceClass, sourceMethod);
  231. }
  232. public void entering(String sourceClass, String sourceMethod, Object param1) {
  233. delegate.entering(sourceClass, sourceMethod, param1);
  234. }
  235. public void entering(String sourceClass, String sourceMethod, Object[] params) {
  236. delegate.entering(sourceClass, sourceMethod, params);
  237. }
  238. public void exiting(String sourceClass, String sourceMethod) {
  239. delegate.exiting(sourceClass, sourceMethod);
  240. }
  241. public void exiting(String sourceClass, String sourceMethod, Object result) {
  242. delegate.exiting(sourceClass, sourceMethod, result);
  243. }
  244. public void throwing(String sourceClass, String sourceMethod, Throwable thrown) {
  245. delegate.throwing(sourceClass, sourceMethod, thrown);
  246. }
  247. public void severe(String msg) {
  248. delegate.severe(msg);
  249. }
  250. public void warning(String msg) {
  251. delegate.warning(msg);
  252. }
  253. public void info(String msg) {
  254. delegate.info(msg);
  255. }
  256. public void config(String msg) {
  257. delegate.config(msg);
  258. }
  259. public void fine(String msg) {
  260. delegate.fine(msg);
  261. }
  262. public void finer(String msg) {
  263. delegate.finer(msg);
  264. }
  265. public void finest(String msg) {
  266. delegate.finest(msg);
  267. }
  268. public void severe(Supplier<String> msgSupplier) {
  269. delegate.severe(msgSupplier);
  270. }
  271. public void warning(Supplier<String> msgSupplier) {
  272. delegate.warning(msgSupplier);
  273. }
  274. public void info(Supplier<String> msgSupplier) {
  275. delegate.info(msgSupplier);
  276. }
  277. public void config(Supplier<String> msgSupplier) {
  278. delegate.config(msgSupplier);
  279. }
  280. public void fine(Supplier<String> msgSupplier) {
  281. delegate.fine(msgSupplier);
  282. }
  283. public void finer(Supplier<String> msgSupplier) {
  284. delegate.finer(msgSupplier);
  285. }
  286. public void finest(Supplier<String> msgSupplier) {
  287. delegate.finest(msgSupplier);
  288. }
  289. }