Mercurial > jhg
changeset 456:909306e412e2
Refactor LogFacility and SessionContext, better API for both
line wrap: on
line diff
--- a/cmdline/org/tmatesoft/hg/console/Main.java Wed Jun 13 21:07:39 2012 +0200 +++ b/cmdline/org/tmatesoft/hg/console/Main.java Mon Jun 18 16:54:00 2012 +0200 @@ -18,6 +18,7 @@ import static org.tmatesoft.hg.repo.HgRepository.TIP; import static org.tmatesoft.hg.repo.HgRepository.WORKING_COPY; +import static org.tmatesoft.hg.util.LogFacility.Severity.*; import java.io.File; import java.io.IOException; @@ -72,6 +73,7 @@ import org.tmatesoft.hg.util.Path; import org.tmatesoft.hg.util.PathRewrite; import org.tmatesoft.hg.util.ProgressSupport; +import org.tmatesoft.hg.util.LogFacility.Severity; /** * Various debug dumps. @@ -250,17 +252,17 @@ } private void testConsoleLog() { - LogFacility fc = new StreamLogFacility(true, true, true, System.out); - System.out.printf("isDebug: %s, isInfo:%s\n", fc.isDebug(), fc.isInfo()); - fc.debug(getClass(), "%d", 1); - fc.info(getClass(), "%d\n", 2); - fc.warn(getClass(), "%d\n", 3); - fc.error(getClass(), "%d", 4); + LogFacility fc = new StreamLogFacility(Debug, true, System.out); + System.out.printf("isDebug: %s, isInfo:%s\n", fc.isDebug(), fc.getLevel() == Info); + fc.dump(getClass(), Debug, "%d", 1); + fc.dump(getClass(), Info, "%d\n", 2); + fc.dump(getClass(), Warn, "%d\n", 3); + fc.dump(getClass(), Error, "%d", 4); Exception ex = new Exception(); - fc.debug(getClass(), ex, "message"); - fc.info(getClass(), ex, null); - fc.warn(getClass(), ex, null); - fc.error(getClass(), ex, "message"); + fc.dump(getClass(), Debug, ex, "message"); + fc.dump(getClass(), Info, ex, null); + fc.dump(getClass(), Warn, ex, null); + fc.dump(getClass(), Error, ex, "message"); } private void testTreeTraversal() throws Exception {
--- a/cmdline/org/tmatesoft/hg/console/Status.java Wed Jun 13 21:07:39 2012 +0200 +++ b/cmdline/org/tmatesoft/hg/console/Status.java Mon Jun 18 16:54:00 2012 +0200 @@ -33,6 +33,7 @@ import org.tmatesoft.hg.core.HgStatus.Kind; import org.tmatesoft.hg.core.HgStatusCommand; import org.tmatesoft.hg.core.HgStatusHandler; +import org.tmatesoft.hg.util.Outcome; import org.tmatesoft.hg.util.Path; /** @@ -86,7 +87,7 @@ } } - public void error(Path file, org.tmatesoft.hg.util.Outcome s) { + public void error(Path file, Outcome s) { System.out.printf("FAILURE: %s %s\n", s.getMessage(), file); s.getException().printStackTrace(System.out); }
--- a/src/org/tmatesoft/hg/core/HgLogCommand.java Wed Jun 13 21:07:39 2012 +0200 +++ b/src/org/tmatesoft/hg/core/HgLogCommand.java Mon Jun 18 16:54:00 2012 +0200 @@ -17,6 +17,7 @@ package org.tmatesoft.hg.core; import static org.tmatesoft.hg.repo.HgRepository.TIP; +import static org.tmatesoft.hg.util.LogFacility.Severity.Error; import java.util.ArrayList; import java.util.Arrays; @@ -37,10 +38,10 @@ import org.tmatesoft.hg.repo.HgInternals; import org.tmatesoft.hg.repo.HgInvalidControlFileException; import org.tmatesoft.hg.repo.HgInvalidStateException; +import org.tmatesoft.hg.repo.HgParentChildMap; import org.tmatesoft.hg.repo.HgRepository; import org.tmatesoft.hg.repo.HgRuntimeException; import org.tmatesoft.hg.repo.HgStatusCollector; -import org.tmatesoft.hg.repo.HgParentChildMap; import org.tmatesoft.hg.util.CancelSupport; import org.tmatesoft.hg.util.CancelledException; import org.tmatesoft.hg.util.Pair; @@ -545,7 +546,7 @@ } } if (!sanity) { - HgInternals.getContext(repo).getLog().error(getClass(), "Index of revision %d:%s doesn't match any of requested", cs.getRevisionIndex(), cs.getNodeid().shortNotation()); + HgInternals.getContext(repo).getLog().dump(getClass(), Error, "Index of revision %d:%s doesn't match any of requested", cs.getRevisionIndex(), cs.getNodeid().shortNotation()); } assert sanity; }
--- a/src/org/tmatesoft/hg/core/SessionContext.java Wed Jun 13 21:07:39 2012 +0200 +++ b/src/org/tmatesoft/hg/core/SessionContext.java Mon Jun 18 16:54:00 2012 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011 TMate Software Ltd + * Copyright (c) 2011-2012 TMate Software Ltd * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,24 +16,33 @@ */ package org.tmatesoft.hg.core; -import org.tmatesoft.hg.internal.Experimental; import org.tmatesoft.hg.util.LogFacility; /** - * WORK IN PROGRESS + * Access to objects that might need to be shared between various distinct operations ran during the same working session + * (i.e. caches, log, etc.). It's unspecified whether session context is per repository or can span multiple repositories * - * Access to objects that might need to be shared between various distinct operations ran during the same working session - * (i.e. caches, log, etc.). It's unspecified whether session context is per repository or can span multiple repositories + * <p>Note, API is likely to be extended in future versions, adding more object to share. * * @author Artem Tikhomirov * @author TMate Software Ltd. */ -@Experimental(reason="Work in progress") -public interface SessionContext { - LogFacility getLog(); +public abstract class SessionContext { + // abstract class to facilitate adding more functionality without API break /** - * LIKELY TO CHANGE TO STANDALONE CONFIGURATION OBJECT + * Access wrapper for a system log facility. + * @return facility to direct dumps to, never <code>null</code> */ - Object getProperty(String name, Object defaultValue); + public abstract LogFacility getLog(); + + /** + * Access configuration parameters of the session. + * @param name name of the session configuration parameter + * @param defaultValue value to return if parameter is not configured + * @return value of the session parameter, defaultValue if none found + */ + public abstract Object getConfigurationProperty(String name, Object defaultValue); + // perhaps, later may add Configuration object, with PropertyMarshal's helpers + // e.g. when there's standalone Caches and WritableSessionProperties objects }
--- a/src/org/tmatesoft/hg/internal/BasicSessionContext.java Wed Jun 13 21:07:39 2012 +0200 +++ b/src/org/tmatesoft/hg/internal/BasicSessionContext.java Mon Jun 18 16:54:00 2012 +0200 @@ -21,13 +21,14 @@ import org.tmatesoft.hg.core.SessionContext; import org.tmatesoft.hg.util.LogFacility; +import org.tmatesoft.hg.util.LogFacility.Severity; /** * * @author Artem Tikhomirov * @author TMate Software Ltd. */ -public class BasicSessionContext implements SessionContext { +public class BasicSessionContext extends SessionContext { private LogFacility logFacility; private final Map<String, Object> properties; @@ -42,25 +43,23 @@ properties = propertyOverrides == null ? Collections.<String,Object>emptyMap() : (Map<String, Object>) propertyOverrides; } + @Override public LogFacility getLog() { // e.g. for exceptions that we can't handle but log (e.g. FileNotFoundException when we've checked beforehand file.canRead() if (logFacility == null) { - boolean needDebug = _getBooleanProperty("hg.consolelog.debug", false); - boolean needInfo = needDebug || _getBooleanProperty("hg.consolelog.info", false); - logFacility = new StreamLogFacility(needDebug, needInfo, true, System.out); + PropertyMarshal pm = new PropertyMarshal(this); + boolean needDebug = pm.getBoolean("hg4j.consolelog.debug", false); + boolean needInfo = pm.getBoolean("hg4j.consolelog.info", false); + boolean needTime = pm.getBoolean("hg4j.consolelog.tstamp", true); + Severity l = needDebug ? Severity.Debug : (needInfo ? Severity.Info : Severity.Warn); + logFacility = new StreamLogFacility(l, needTime, System.out); } return logFacility; } - private boolean _getBooleanProperty(String name, boolean defaultValue) { - // can't use <T> and unchecked cast because got no confidence passed properties are strictly of the kind of my default values, - // i.e. if boolean from outside comes as "true", while I pass default as Boolean or vice versa. - Object p = getProperty(name, defaultValue); - return p instanceof Boolean ? ((Boolean) p).booleanValue() : Boolean.parseBoolean(String.valueOf(p)); - } - - // TODO specific helpers for boolean and int values - public Object getProperty(String name, Object defaultValue) { + // specific helpers for boolean and int values are available from PropertyMarshal + @Override + public Object getConfigurationProperty(String name, Object defaultValue) { // NOTE, this method is invoked from getLog(), hence do not call getLog from here unless changed appropriately Object value = properties.get(name); if (value != null) {
--- a/src/org/tmatesoft/hg/internal/DataAccessProvider.java Wed Jun 13 21:07:39 2012 +0200 +++ b/src/org/tmatesoft/hg/internal/DataAccessProvider.java Mon Jun 18 16:54:00 2012 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010-2011 TMate Software Ltd + * Copyright (c) 2010-2012 TMate Software Ltd * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,6 +16,9 @@ */ package org.tmatesoft.hg.internal; +import static org.tmatesoft.hg.util.LogFacility.Severity.Error; +import static org.tmatesoft.hg.util.LogFacility.Severity.Warn; + import java.io.File; import java.io.FileInputStream; import java.io.IOException; @@ -46,25 +49,22 @@ private static final int DEFAULT_MAPIO_BUFFER = DEFAULT_MAPIO_LIMIT; // same as default boundary private final int mapioMagicBoundary; - private final int bufferSize; + private final int bufferSize, mapioBufSize; private final SessionContext context; public DataAccessProvider(SessionContext ctx) { - this(ctx, getConfigOption(ctx, CFG_PROPERTY_MAPIO_LIMIT, DEFAULT_MAPIO_LIMIT), getConfigOption(ctx, CFG_PROPERTY_FILE_BUFFER_SIZE, DEFAULT_FILE_BUFFER)); + context = ctx; + PropertyMarshal pm = new PropertyMarshal(ctx); + mapioMagicBoundary = pm.getInt(CFG_PROPERTY_MAPIO_LIMIT, DEFAULT_MAPIO_LIMIT); + bufferSize = pm.getInt(CFG_PROPERTY_FILE_BUFFER_SIZE, DEFAULT_FILE_BUFFER); + mapioBufSize = pm.getInt(CFG_PROPERTY_MAPIO_BUFFER_SIZE, DEFAULT_MAPIO_BUFFER); } - private static int getConfigOption(SessionContext ctx, String optName, int defaultValue) { - Object v = ctx.getProperty(optName, defaultValue); - if (false == v instanceof Number) { - v = Integer.parseInt(v.toString()); - } - return ((Number) v).intValue(); - } - - public DataAccessProvider(SessionContext ctx, int mapioBoundary, int regularBufferSize) { + public DataAccessProvider(SessionContext ctx, int mapioBoundary, int regularBufferSize, int mapioBufferSize) { context = ctx; mapioMagicBoundary = mapioBoundary == 0 ? Integer.MAX_VALUE : mapioBoundary; bufferSize = regularBufferSize; + mapioBufSize = mapioBufferSize; } public DataAccess create(File f) { @@ -76,7 +76,6 @@ long flen = fc.size(); if (flen > mapioMagicBoundary) { // TESTS: bufLen of 1024 was used to test MemMapFileAccess - int mapioBufSize = getConfigOption(context, CFG_PROPERTY_MAPIO_BUFFER_SIZE, DEFAULT_MAPIO_BUFFER); return new MemoryMapFileAccess(fc, flen, mapioBufSize, context.getLog()); } else { // XXX once implementation is more or less stable, @@ -88,7 +87,7 @@ } } catch (IOException ex) { // unlikely to happen, we've made sure file exists. - context.getLog().error(getClass(), ex, null); + context.getLog().dump(getClass(), Error, ex, null); } return new DataAccess(); // non-null, empty. } @@ -177,14 +176,14 @@ } if (i == 0) { // if first attempt failed, try to free some virtual memory, see Issue 30 for details - logFacility.warn(getClass(), ex, "Memory-map failed, gonna try gc() to free virtual memory"); + logFacility.dump(getClass(), Warn, ex, "Memory-map failed, gonna try gc() to free virtual memory"); } try { buffer = null; System.gc(); Thread.sleep((1+i) * 1000); } catch (Throwable t) { - logFacility.error(getClass(), t, "Bad luck"); + logFacility.dump(getClass(), Error, t, "Bad luck"); } } } @@ -230,7 +229,7 @@ try { fileChannel.close(); } catch (IOException ex) { - logFacility.debug(getClass(), ex, null); + logFacility.dump(getClass(), Warn, ex, null); } fileChannel = null; } @@ -364,7 +363,7 @@ try { fileChannel.close(); } catch (IOException ex) { - logFacility.debug(getClass(), ex, null); + logFacility.dump(getClass(), Warn, ex, null); } fileChannel = null; }
--- a/src/org/tmatesoft/hg/internal/EncodingHelper.java Wed Jun 13 21:07:39 2012 +0200 +++ b/src/org/tmatesoft/hg/internal/EncodingHelper.java Mon Jun 18 16:54:00 2012 +0200 @@ -16,6 +16,8 @@ */ package org.tmatesoft.hg.internal; +import static org.tmatesoft.hg.util.LogFacility.Severity.Error; + import java.nio.ByteBuffer; import java.nio.CharBuffer; import java.nio.charset.CharacterCodingException; @@ -71,7 +73,7 @@ bb.get(rv, 0, rv.length); return rv; } catch (CharacterCodingException ex) { - sessionContext.getLog().error(getClass(), ex, String.format("Use of charset %s failed, resort to system default", charset().name())); + sessionContext.getLog().dump(getClass(), Error, ex, String.format("Use of charset %s failed, resort to system default", charset().name())); // resort to system-default return s.getBytes(); } @@ -88,7 +90,7 @@ try { return decoder.decode(ByteBuffer.wrap(data, start, length)).toString(); } catch (CharacterCodingException ex) { - sessionContext.getLog().error(getClass(), ex, String.format("Use of charset %s failed, resort to system default", charset().name())); + sessionContext.getLog().dump(getClass(), Error, ex, String.format("Use of charset %s failed, resort to system default", charset().name())); // resort to system-default return new String(data, start, length); }
--- a/src/org/tmatesoft/hg/internal/Internals.java Wed Jun 13 21:07:39 2012 +0200 +++ b/src/org/tmatesoft/hg/internal/Internals.java Mon Jun 18 16:54:00 2012 +0200 @@ -17,6 +17,7 @@ package org.tmatesoft.hg.internal; import static org.tmatesoft.hg.internal.RequiresFile.*; +import static org.tmatesoft.hg.util.LogFacility.Severity.Error; import java.io.File; import java.io.FileOutputStream; @@ -83,8 +84,7 @@ public Internals(SessionContext ctx) { sessionContext = ctx; isCaseSensitiveFileSystem = !runningOnWindows(); - Object p = ctx.getProperty(CFG_PROPERTY_REVLOG_STREAM_CACHE, true); - shallCacheRevlogsInRepo = p instanceof Boolean ? ((Boolean) p).booleanValue() : Boolean.parseBoolean(String.valueOf(p)); + shallCacheRevlogsInRepo = new PropertyMarshal(ctx).getBoolean(CFG_PROPERTY_REVLOG_STREAM_CACHE, true); } public void parseRequires(HgRepository hgRepo, File requiresFile) throws HgInvalidControlFileException { @@ -173,7 +173,7 @@ } private Charset getFileEncoding() { - Object altEncoding = sessionContext.getProperty(CFG_PROPERTY_FS_FILENAME_ENCODING, null); + Object altEncoding = sessionContext.getConfigurationProperty(CFG_PROPERTY_FS_FILENAME_ENCODING, null); Charset cs; if (altEncoding == null) { cs = Charset.defaultCharset(); @@ -183,7 +183,7 @@ } catch (IllegalArgumentException ex) { // both IllegalCharsetNameException and UnsupportedCharsetException are subclasses of IAE, too // not severe enough to throw an exception, imo. Just record the fact it's bad ad we ignore it - sessionContext.getLog().error(Internals.class, ex, String.format("Bad configuration value for filename encoding %s", altEncoding)); + sessionContext.getLog().dump(Internals.class, Error, ex, String.format("Bad configuration value for filename encoding %s", altEncoding)); cs = Charset.defaultCharset(); } } @@ -224,7 +224,7 @@ */ private static File findHgInstallRoot(SessionContext ctx) { // let clients to override Hg install location - String p = (String) ctx.getProperty(CFG_PROPERTY_HG_INSTALL_ROOT, null); + String p = (String) ctx.getConfigurationProperty(CFG_PROPERTY_HG_INSTALL_ROOT, null); if (p != null) { return new File(p); }
--- a/src/org/tmatesoft/hg/internal/KeywordFilter.java Wed Jun 13 21:07:39 2012 +0200 +++ b/src/org/tmatesoft/hg/internal/KeywordFilter.java Mon Jun 18 16:54:00 2012 +0200 @@ -16,6 +16,8 @@ */ package org.tmatesoft.hg.internal; +import static org.tmatesoft.hg.util.LogFacility.Severity.Error; + import java.nio.ByteBuffer; import java.util.ArrayList; import java.util.Date; @@ -263,7 +265,7 @@ int csetRev = repo.getFileNode(path).getChangesetRevisionIndex(HgRepository.TIP); return repo.getChangelog().getRevision(csetRev).shortNotation(); } catch (HgRuntimeException ex) { - HgInternals.getContext(repo).getLog().error(getClass(), ex, null); + HgInternals.getContext(repo).getLog().dump(getClass(), Error, ex, null); return Nodeid.NULL.shortNotation(); // XXX perhaps, might return anything better? Not sure how hg approaches this. } } @@ -272,7 +274,7 @@ try { return getChangeset().user(); } catch (HgRuntimeException ex) { - HgInternals.getContext(repo).getLog().error(getClass(), ex, null); + HgInternals.getContext(repo).getLog().dump(getClass(), Error, ex, null); return ""; } } @@ -282,7 +284,7 @@ try { d = getChangeset().date(); } catch (HgRuntimeException ex) { - HgInternals.getContext(repo).getLog().error(getClass(), ex, null); + HgInternals.getContext(repo).getLog().dump(getClass(), Error, ex, null); d = new Date(0l); } return String.format("%tY/%<tm/%<td %<tH:%<tM:%<tS", d);
--- a/src/org/tmatesoft/hg/internal/NewlineFilter.java Wed Jun 13 21:07:39 2012 +0200 +++ b/src/org/tmatesoft/hg/internal/NewlineFilter.java Mon Jun 18 16:54:00 2012 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011 TMate Software Ltd + * Copyright (c) 2011-2012 TMate Software Ltd * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -21,6 +21,7 @@ import static org.tmatesoft.hg.internal.Filter.Direction.FromRepo; import static org.tmatesoft.hg.internal.Filter.Direction.ToRepo; import static org.tmatesoft.hg.internal.KeywordFilter.copySlice; +import static org.tmatesoft.hg.util.LogFacility.Severity.Warn; import java.io.File; import java.io.IOException; @@ -315,7 +316,7 @@ try { hgeol.addLocation(cfgFile); } catch (IOException ex) { - HgInternals.getContext(hgRepo).getLog().warn(getClass(), ex, null); + HgInternals.getContext(hgRepo).getLog().dump(getClass(), Warn, ex, null); } nativeRepoFormat = hgeol.getSection("repository").get("native"); if (nativeRepoFormat == null) { @@ -338,7 +339,7 @@ } else if ("BIN".equals(e.getValue())) { binPatterns.add(e.getKey()); } else { - HgInternals.getContext(hgRepo).getLog().warn(getClass(), "Can't recognize .hgeol entry: %s for %s", e.getValue(), e.getKey()); + HgInternals.getContext(hgRepo).getLog().dump(getClass(), Warn, "Can't recognize .hgeol entry: %s for %s", e.getValue(), e.getKey()); } } if (!crlfPatterns.isEmpty()) {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/org/tmatesoft/hg/internal/PropertyMarshal.java Mon Jun 18 16:54:00 2012 +0200 @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2012 TMate Software Ltd + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * For information on how to redistribute this software under + * the terms of a license other than GNU General Public License + * contact TMate Software at support@hg4j.com + */ +package org.tmatesoft.hg.internal; + +import org.tmatesoft.hg.core.SessionContext; + +/** + * + * @author Artem Tikhomirov + * @author TMate Software Ltd. + */ +public class PropertyMarshal { + + private final SessionContext sessionContext; + + public PropertyMarshal(SessionContext ctx) { + sessionContext = ctx; + } + + public boolean getBoolean(String propertyName, boolean defaultValue) { + // can't use <T> and unchecked cast because got no confidence passed properties are strictly of the kind of my default values, + // i.e. if boolean from outside comes as "true", while I pass default as Boolean or vice versa. + Object p = sessionContext.getConfigurationProperty(propertyName, defaultValue); + return p instanceof Boolean ? ((Boolean) p).booleanValue() : Boolean.parseBoolean(String.valueOf(p)); + } + + public int getInt(String propertyName, int defaultValue) { + Object v = sessionContext.getConfigurationProperty(propertyName, defaultValue); + if (false == v instanceof Number) { + v = Integer.parseInt(String.valueOf(v)); + } + return ((Number) v).intValue(); + } +}
--- a/src/org/tmatesoft/hg/internal/StreamLogFacility.java Wed Jun 13 21:07:39 2012 +0200 +++ b/src/org/tmatesoft/hg/internal/StreamLogFacility.java Mon Jun 18 16:54:00 2012 +0200 @@ -16,6 +16,8 @@ */ package org.tmatesoft.hg.internal; +import static org.tmatesoft.hg.util.LogFacility.Severity.Info; + import java.io.PrintStream; import org.tmatesoft.hg.util.LogFacility; @@ -29,13 +31,14 @@ public class StreamLogFacility implements LogFacility { private final boolean isDebug; - private final boolean isInfo; + private final Severity severity; protected final boolean timestamp; protected final PrintStream outStream; - public StreamLogFacility(boolean pringDebug, boolean printInfo, boolean needTimestamp, PrintStream out) { - isDebug = pringDebug; - isInfo = printInfo; + public StreamLogFacility(Severity level, boolean needTimestamp, PrintStream out) { + assert level != null; + severity = level; + isDebug = level == Severity.Debug; timestamp = needTimestamp; outStream = out; } @@ -43,56 +46,24 @@ public boolean isDebug() { return isDebug; } - - public boolean isInfo() { - return isInfo; - } - - public void debug(Class<?> src, String format, Object... args) { - if (!isDebug) { - return; - } - printf("DEBUG", src, format, args); - } - - public void info(Class<?> src, String format, Object... args) { - if (!isInfo) { - return; - } - printf("INFO", src, format, args); - } - - public void warn(Class<?> src, String format, Object... args) { - printf("WARN", src, format, args); + + public Severity getLevel() { + return severity; } - public void error(Class<?> src, String format, Object... args) { - printf("ERROR", src, format, args); - } - - public void debug(Class<?> src, Throwable th, String message) { - if (!isDebug) { - return; + public void dump(Class<?> src, Severity severity, String format, Object... args) { + if (severity.ordinal() >= getLevel().ordinal()) { + printf(severity, src, format, args); } - printf("DEBUG", src, th, message); } - public void info(Class<?> src, Throwable th, String message) { - if (!isInfo) { - return; + public void dump(Class<?> src, Severity severity, Throwable th, String message) { + if (severity.ordinal() >= getLevel().ordinal()) { + printf(severity, src, th, message); } - printf("INFO", src, th, message); } - public void warn(Class<?> src, Throwable th, String message) { - printf("WARN", src, th, message); - } - - public void error(Class<?> src, Throwable th, String message) { - printf("ERROR", src, th, message); - } - - protected void printf(String level, Class<?> src, String format, Object... args) { + protected void printf(Severity level, Class<?> src, String format, Object... args) { String msg = String.format(format, args); if (timestamp) { outStream.printf(isDebug ? "%tT.%1$tL " : "%tT ", System.currentTimeMillis()); @@ -104,17 +75,17 @@ } outStream.printf("(%s) ", cn); } - outStream.printf("%s: %s", level, msg); + outStream.printf("%s: %s", level.toString().toUpperCase(), msg); if (format.length() == 0 || format.charAt(format.length() - 1) != '\n') { outStream.println(); } } - protected void printf(String level, Class<?> src, Throwable th, String msg) { + protected void printf(Severity level, Class<?> src, Throwable th, String msg) { if (msg != null || timestamp || isDebug || th == null) { printf(level, src, msg == null ? "" : msg, (Object[]) null); } if (th != null) { - if (isDebug || isInfo) { + if (getLevel().ordinal() <= Info.ordinal()) { // full stack trace th.printStackTrace(outStream); } else { @@ -126,6 +97,6 @@ // alternative to hardcore System.out where SessionContext is not available now (or ever) public static LogFacility newDefault() { - return new StreamLogFacility(true, true, true, System.out); + return new StreamLogFacility(Severity.Debug, true, System.out); } }
--- a/src/org/tmatesoft/hg/repo/HgBranches.java Wed Jun 13 21:07:39 2012 +0200 +++ b/src/org/tmatesoft/hg/repo/HgBranches.java Mon Jun 18 16:54:00 2012 +0200 @@ -16,6 +16,9 @@ */ package org.tmatesoft.hg.repo; +import static org.tmatesoft.hg.util.LogFacility.Severity.Error; +import static org.tmatesoft.hg.util.LogFacility.Severity.Warn; + import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.File; @@ -98,24 +101,24 @@ return lastInCache; } catch (IOException ex) { // log error, but otherwise do nothing - repo.getContext().getLog().warn(getClass(), ex, null); + repo.getContext().getLog().dump(getClass(), Warn, ex, null); // FALL THROUGH to return -1 indicating no cache information } catch (NumberFormatException ex) { - repo.getContext().getLog().warn(getClass(), ex, null); + repo.getContext().getLog().dump(getClass(), Warn, ex, null); // FALL THROUGH } catch (HgInvalidControlFileException ex) { // shall not happen, thus log as error - repo.getContext().getLog().error(getClass(), ex, null); + repo.getContext().getLog().dump(getClass(), Error, ex, null); // FALL THROUGH } catch (HgInvalidRevisionException ex) { - repo.getContext().getLog().error(getClass(), ex, null); + repo.getContext().getLog().dump(getClass(), Error, ex, null); // FALL THROUGH } finally { if (br != null) { try { br.close(); } catch (IOException ex) { - repo.getContext().getLog().info(getClass(), ex, null); // ignore + repo.getContext().getLog().dump(getClass(), Warn, ex, null); // ignore } } }
--- a/src/org/tmatesoft/hg/repo/HgDataFile.java Wed Jun 13 21:07:39 2012 +0200 +++ b/src/org/tmatesoft/hg/repo/HgDataFile.java Mon Jun 18 16:54:00 2012 +0200 @@ -18,6 +18,7 @@ import static org.tmatesoft.hg.repo.HgInternals.wrongRevisionIndex; import static org.tmatesoft.hg.repo.HgRepository.*; +import static org.tmatesoft.hg.util.LogFacility.Severity.*; import java.io.ByteArrayOutputStream; import java.io.File; @@ -181,7 +182,7 @@ try { fc.close(); } catch (IOException ex) { - getRepo().getContext().getLog().info(getClass(), ex, null); + getRepo().getContext().getLog().dump(getClass(), Warn, ex, null); } } } @@ -207,7 +208,7 @@ final int csetRevIndex; if (p.isNull()) { // no dirstate parents - getRepo().getContext().getLog().info(getClass(), "No dirstate parents, resort to TIP", getPath()); + getRepo().getContext().getLog().dump(getClass(), Info, "No dirstate parents, resort to TIP", getPath()); // if it's a repository with no dirstate, use TIP then csetRevIndex = clog.getLastRevision(); if (csetRevIndex == -1) { @@ -607,7 +608,7 @@ break; } if (key == null || lastColon == -1 || i <= lastColon) { - log.error(getClass(), "Missing key in file revision metadata at index %d", i); + log.dump(getClass(), Error, "Missing key in file revision metadata at index %d", i); } value = new String(bos.toByteArray()).trim(); bos.reset();
--- a/src/org/tmatesoft/hg/repo/HgDirstate.java Wed Jun 13 21:07:39 2012 +0200 +++ b/src/org/tmatesoft/hg/repo/HgDirstate.java Mon Jun 18 16:54:00 2012 +0200 @@ -17,6 +17,7 @@ package org.tmatesoft.hg.repo; import static org.tmatesoft.hg.core.Nodeid.NULL; +import static org.tmatesoft.hg.util.LogFacility.Severity.Debug; import java.io.BufferedReader; import java.io.File; @@ -35,6 +36,7 @@ import org.tmatesoft.hg.util.Pair; import org.tmatesoft.hg.util.Path; import org.tmatesoft.hg.util.PathRewrite; +import org.tmatesoft.hg.util.LogFacility.Severity; /** @@ -141,7 +143,7 @@ } else if (state == 'm') { merged.put(r.name1, r); } else { - repo.getContext().getLog().warn(getClass(), "Dirstate record for file %s (size: %d, tstamp:%d) has unknown state '%c'", r.name1, r.size(), r.time, state); + repo.getContext().getLog().dump(getClass(), Severity.Warn, "Dirstate record for file %s (size: %d, tstamp:%d) has unknown state '%c'", r.name1, r.size(), r.time, state); } } } catch (IOException ex) { @@ -205,7 +207,7 @@ branch = b == null || b.length() == 0 ? HgRepository.DEFAULT_BRANCH_NAME : b; r.close(); } catch (FileNotFoundException ex) { - repo.getContext().getLog().debug(HgDirstate.class, ex, null); // log verbose debug, exception might be legal here + repo.getContext().getLog().dump(HgDirstate.class, Debug, ex, null); // log verbose debug, exception might be legal here // IGNORE } catch (IOException ex) { throw new HgInvalidControlFileException("Error reading file with branch information", ex, branchFile);
--- a/src/org/tmatesoft/hg/repo/HgLookup.java Wed Jun 13 21:07:39 2012 +0200 +++ b/src/org/tmatesoft/hg/repo/HgLookup.java Mon Jun 18 16:54:00 2012 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010-2011 TMate Software Ltd + * Copyright (c) 2010-2012 TMate Software Ltd * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,6 +16,8 @@ */ package org.tmatesoft.hg.repo; +import static org.tmatesoft.hg.util.LogFacility.Severity.Warn; + import java.io.File; import java.io.IOException; import java.net.MalformedURLException; @@ -135,7 +137,7 @@ globalCfg.addLocation(new File(System.getProperty("user.home"), ".hgrc")); } catch (IOException ex) { // XXX perhaps, makes sense to let caller/client know that we've failed to read global config? - getContext().getLog().warn(getClass(), ex, null); + getContext().getLog().dump(getClass(), Warn, ex, null); } } return globalCfg;
--- a/src/org/tmatesoft/hg/repo/HgManifest.java Wed Jun 13 21:07:39 2012 +0200 +++ b/src/org/tmatesoft/hg/repo/HgManifest.java Mon Jun 18 16:54:00 2012 +0200 @@ -18,6 +18,7 @@ import static org.tmatesoft.hg.core.Nodeid.NULL; import static org.tmatesoft.hg.repo.HgRepository.*; +import static org.tmatesoft.hg.util.LogFacility.Severity.Info; import java.io.ByteArrayOutputStream; import java.io.IOException; @@ -38,6 +39,7 @@ import org.tmatesoft.hg.util.CancelSupport; import org.tmatesoft.hg.util.Path; import org.tmatesoft.hg.util.ProgressSupport; +import org.tmatesoft.hg.util.LogFacility.Severity; /** @@ -167,7 +169,7 @@ i++; } while (manifestFirst == BAD_REVISION && csetFirst+i <= csetLast); if (manifestFirst == BAD_REVISION) { - getRepo().getContext().getLog().info(getClass(), "None of changesets [%d..%d] have associated manifest revision", csetFirst, csetLast); + getRepo().getContext().getLog().dump(getClass(), Info, "None of changesets [%d..%d] have associated manifest revision", csetFirst, csetLast); // we ran through all revisions in [start..end] and none of them had manifest. // we reported that to inspector and proceeding is done now. return; @@ -616,7 +618,7 @@ // TODO calculate those missing effectively (e.g. cache and sort nodeids to speed lookup // right away in the #next (may refactor ParentWalker's sequential and sorted into dedicated helper and reuse here) if (manifest.isNull()) { - repo.getContext().getLog().warn(getClass(), "Changeset %d has no associated manifest entry", u); + repo.getContext().getLog().dump(getClass(), Severity.Warn, "Changeset %d has no associated manifest entry", u); // keep -1 in the changelog2manifest map. } else { changelog2manifest[u] = repo.getManifest().getRevisionIndex(manifest);
--- a/src/org/tmatesoft/hg/repo/HgRemoteRepository.java Wed Jun 13 21:07:39 2012 +0200 +++ b/src/org/tmatesoft/hg/repo/HgRemoteRepository.java Mon Jun 18 16:54:00 2012 +0200 @@ -16,6 +16,8 @@ */ package org.tmatesoft.hg.repo; +import static org.tmatesoft.hg.util.LogFacility.Severity.Info; + import java.io.BufferedReader; import java.io.File; import java.io.FileOutputStream; @@ -55,6 +57,7 @@ import org.tmatesoft.hg.core.HgRepositoryNotFoundException; import org.tmatesoft.hg.core.Nodeid; import org.tmatesoft.hg.core.SessionContext; +import org.tmatesoft.hg.internal.PropertyMarshal; /** * WORK IN PROGRESS, DO NOT USE @@ -80,8 +83,7 @@ } this.url = url; sessionContext = ctx; - Object debugProp = ctx.getProperty("hg4j.remote.debug", false); - debug = debugProp instanceof Boolean ? ((Boolean) debugProp).booleanValue() : Boolean.parseBoolean(String.valueOf(debugProp)); + debug = new PropertyMarshal(ctx).getBoolean("hg4j.remote.debug", false); if ("https".equals(url.getProtocol())) { try { sslContext = SSLContext.getInstance("SSL"); @@ -116,7 +118,7 @@ ai = tempNode.get("xxx", null); tempNode.removeNode(); } catch (BackingStoreException ex) { - sessionContext.getLog().info(getClass(), ex, null); + sessionContext.getLog().dump(getClass(), Info, ex, null); // IGNORE } authInfo = ai;
--- a/src/org/tmatesoft/hg/repo/HgRepository.java Wed Jun 13 21:07:39 2012 +0200 +++ b/src/org/tmatesoft/hg/repo/HgRepository.java Mon Jun 18 16:54:00 2012 +0200 @@ -16,6 +16,8 @@ */ package org.tmatesoft.hg.repo; +import static org.tmatesoft.hg.util.LogFacility.Severity.*; + import java.io.File; import java.io.IOException; import java.io.StringReader; @@ -201,12 +203,12 @@ tags.readGlobal(new StringReader(content)); } catch (CancelledException ex) { // IGNORE, can't happen, we did not configure cancellation - getContext().getLog().debug(getClass(), ex, null); + getContext().getLog().dump(getClass(), Debug, ex, null); } catch (IOException ex) { // UnsupportedEncodingException can't happen (UTF8) // only from readGlobal. Need to reconsider exceptions thrown from there: // BufferedReader wraps String and unlikely to throw IOException, perhaps, log is enough? - getContext().getLog().error(getClass(), ex, null); + getContext().getLog().dump(getClass(), Error, ex, null); // XXX need to decide what to do this. failure to read single revision shall not break complete cycle } } @@ -218,7 +220,7 @@ file2read = new File(repoDir, "localtags"); tags.readLocal(file2read); } catch (IOException ex) { - getContext().getLog().error(getClass(), ex, null); + getContext().getLog().dump(getClass(), Error, ex, null); throw new HgInvalidControlFileException("Failed to read tags", ex, file2read); } } @@ -314,7 +316,7 @@ repoConfig = new HgRepoConfig(configFile); } catch (IOException ex) { String m = "Errors while reading user configuration file"; - getContext().getLog().warn(getClass(), ex, m); + getContext().getLog().dump(getClass(), Warn, ex, m); return new HgRepoConfig(new ConfigFile()); // empty config, do not cache, allow to try once again //throw new HgInvalidControlFileException(m, ex, null); } @@ -361,11 +363,11 @@ try { final List<String> errors = ignore.read(ignoreFile); if (errors != null) { - getContext().getLog().warn(getClass(), "Syntax errors parsing .hgignore:\n%s", Internals.join(errors, ",\n")); + getContext().getLog().dump(getClass(), Warn, "Syntax errors parsing .hgignore:\n%s", Internals.join(errors, ",\n")); } } catch (IOException ex) { final String m = "Error reading .hgignore file"; - getContext().getLog().warn(getClass(), ex, m); + getContext().getLog().dump(getClass(), Warn, ex, m); // throw new HgInvalidControlFileException(m, ex, ignoreFile); } } @@ -400,7 +402,7 @@ fake.deleteOnExit(); return new RevlogStream(dataAccess, fake); } catch (IOException ex) { - getContext().getLog().info(getClass(), ex, null); + getContext().getLog().dump(getClass(), Info, ex, null); } } }
--- a/src/org/tmatesoft/hg/repo/HgRepositoryFiles.java Wed Jun 13 21:07:39 2012 +0200 +++ b/src/org/tmatesoft/hg/repo/HgRepositoryFiles.java Mon Jun 18 16:54:00 2012 +0200 @@ -16,7 +16,6 @@ */ package org.tmatesoft.hg.repo; -import org.tmatesoft.hg.internal.Experimental; /** * Names of some Mercurial configuration/service files. @@ -24,7 +23,6 @@ * @author Artem Tikhomirov * @author TMate Software Ltd. */ -@Experimental public enum HgRepositoryFiles { HgIgnore(".hgignore"), HgTags(".hgtags"), HgEol(".hgeol"),
--- a/src/org/tmatesoft/hg/repo/HgTags.java Wed Jun 13 21:07:39 2012 +0200 +++ b/src/org/tmatesoft/hg/repo/HgTags.java Mon Jun 18 16:54:00 2012 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011 TMate Software Ltd + * Copyright (c) 2011-2012 TMate Software Ltd * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,6 +16,8 @@ */ package org.tmatesoft.hg.repo; +import static org.tmatesoft.hg.util.LogFacility.Severity.Warn; + import java.io.BufferedReader; import java.io.File; import java.io.FileReader; @@ -107,7 +109,7 @@ continue; } if (line.length() < 40+2 /*nodeid, space and at least single-char tagname*/) { - repo.getContext().getLog().warn(getClass(), "Bad tags line: %s", line); + repo.getContext().getLog().dump(getClass(), Warn, "Bad tags line: %s", line); continue; } int spacePos = line.indexOf(' '); @@ -151,7 +153,7 @@ } } else { - repo.getContext().getLog().warn(getClass(), "Bad tags line: %s", line); + repo.getContext().getLog().dump(getClass(), Warn, "Bad tags line: %s", line); } } }
--- a/src/org/tmatesoft/hg/repo/HgWorkingCopyStatusCollector.java Wed Jun 13 21:07:39 2012 +0200 +++ b/src/org/tmatesoft/hg/repo/HgWorkingCopyStatusCollector.java Mon Jun 18 16:54:00 2012 +0200 @@ -19,6 +19,7 @@ import static java.lang.Math.max; import static java.lang.Math.min; import static org.tmatesoft.hg.repo.HgRepository.*; +import static org.tmatesoft.hg.util.LogFacility.Severity.*; import java.io.File; import java.io.IOException; @@ -33,7 +34,6 @@ import org.tmatesoft.hg.core.Nodeid; import org.tmatesoft.hg.core.SessionContext; import org.tmatesoft.hg.internal.ByteArrayChannel; -import org.tmatesoft.hg.internal.Experimental; import org.tmatesoft.hg.internal.FilterByteChannel; import org.tmatesoft.hg.internal.Internals; import org.tmatesoft.hg.internal.ManifestRevision; @@ -362,7 +362,7 @@ } } } catch (HgRuntimeException ex) { - repo.getContext().getLog().warn(getClass(), ex, null); + repo.getContext().getLog().dump(getClass(), Warn, ex, null); inspector.invalid(fname, ex); } } @@ -451,7 +451,7 @@ inspector.modified(fname); } } catch (HgRuntimeException ex) { - repo.getContext().getLog().warn(getClass(), ex, null); + repo.getContext().getLog().dump(getClass(), Warn, ex, null); inspector.invalid(fname, ex); } baseRevNames.remove(fname); // consumed, processed, handled. @@ -508,7 +508,7 @@ int offset = max(0, x - 4); exp = new String(data, offset, min(data.length - offset, 20)); } - repo.getContext().getLog().debug(getClass(), "expected >>%s<< but got >>%s<<", exp, new String(xx)); + repo.getContext().getLog().dump(getClass(), Debug, "expected >>%s<< but got >>%s<<", exp, new String(xx)); } sameSoFar = false; break; @@ -541,7 +541,7 @@ try { is.close(); } catch (IOException ex) { - repo.getContext().getLog().info(getClass(), ex, null); + repo.getContext().getLog().dump(getClass(), Info, ex, null); } is = f.newInputChannel(); fb.clear(); @@ -553,7 +553,7 @@ } return check.ultimatelyTheSame(); } catch (CancelledException ex) { - repo.getContext().getLog().warn(getClass(), ex, "Unexpected cancellation"); + repo.getContext().getLog().dump(getClass(), Warn, ex, "Unexpected cancellation"); return check.ultimatelyTheSame(); } catch (IOException ex) { throw new HgInvalidFileException("File comparison failed", ex).setFileName(p); @@ -562,7 +562,7 @@ try { is.close(); } catch (IOException ex) { - repo.getContext().getLog().info(getClass(), ex, null); + repo.getContext().getLog().dump(getClass(), Info, ex, null); } } } @@ -612,7 +612,6 @@ * * @return new instance of {@link HgWorkingCopyStatusCollector}, ready to {@link #walk(int, HgStatusInspector) walk} associated working copy */ - @Experimental(reason="Provisional API") public static HgWorkingCopyStatusCollector create(HgRepository hgRepo, Path... paths) { ArrayList<Path> f = new ArrayList<Path>(5); ArrayList<Path> d = new ArrayList<Path>(5); @@ -644,7 +643,6 @@ * * @return new instance of {@link HgWorkingCopyStatusCollector}, ready to {@link #walk(int, HgStatusInspector) walk} associated working copy */ - @Experimental(reason="Provisional API. May add boolean strict argument for those who write smart matchers that can be used in FileWalker") public static HgWorkingCopyStatusCollector create(HgRepository hgRepo, Path.Matcher scope) { FileIterator w = new HgInternals(hgRepo).createWorkingDirWalker(null); FileIterator wf = (scope == null || scope instanceof Path.Matcher.Any) ? w : new FileIteratorFilter(w, scope);
--- a/src/org/tmatesoft/hg/repo/Revlog.java Wed Jun 13 21:07:39 2012 +0200 +++ b/src/org/tmatesoft/hg/repo/Revlog.java Mon Jun 18 16:54:00 2012 +0200 @@ -17,6 +17,7 @@ package org.tmatesoft.hg.repo; import static org.tmatesoft.hg.repo.HgRepository.*; +import static org.tmatesoft.hg.util.LogFacility.Severity.Warn; import java.io.IOException; import java.nio.ByteBuffer; @@ -432,7 +433,7 @@ int consumed = sink.write(buf); if ((consumed == 0 || consumed != buf.position()) && logFacility != null) { - logFacility.warn(getClass(), "Bad data sink when reading revision %d. Reported %d bytes consumed, byt actually read %d", revisionNumber, consumed, buf.position()); + logFacility.dump(getClass(), Warn, "Bad data sink when reading revision %d. Reported %d bytes consumed, byt actually read %d", revisionNumber, consumed, buf.position()); } if (buf.position() == 0) { throw new HgInvalidStateException("Bad sink implementation (consumes no bytes) results in endless loop");
--- a/src/org/tmatesoft/hg/util/LogFacility.java Wed Jun 13 21:07:39 2012 +0200 +++ b/src/org/tmatesoft/hg/util/LogFacility.java Mon Jun 18 16:54:00 2012 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011 TMate Software Ltd + * Copyright (c) 2011-2012 TMate Software Ltd * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,10 +16,9 @@ */ package org.tmatesoft.hg.util; -import org.tmatesoft.hg.internal.Experimental; /** - * WORK IN PROGRESS + * Facility to dump various messages. * * Intention of this class is to abstract away almost any log facility out there clients might be using with the <b>Hg4J</b> library, * not to be a full-fledged logging facility of its own. @@ -30,21 +29,41 @@ * @author Artem Tikhomirov * @author TMate Software Ltd. */ -@Experimental(reason="API might get changed") public interface LogFacility { - - boolean isDebug(); - boolean isInfo(); + + public enum Severity { + Debug, Info, Warn, Error // order is important + } - // src and format never null - void debug(Class<?> src, String format, Object... args); - void info(Class<?> src, String format, Object... args); - void warn(Class<?> src, String format, Object... args); - void error(Class<?> src, String format, Object... args); + /** + * Effective way to avoid attempts to construct debug dumps when they are of no interest. Basically, <code>getLevel() < Info</code> + * + * @return <code>true</code> if interested in debug dumps + */ + boolean isDebug(); - // src shall be non null, either th or message or both - void debug(Class<?> src, Throwable th, String message); - void info(Class<?> src, Throwable th, String message); - void warn(Class<?> src, Throwable th, String message); - void error(Class<?> src, Throwable th, String message); + /** + * + * @return lowest (from {@link Severity#Debug} to {@link Severity#Error} active severity level + */ + Severity getLevel(); + + /** + * Dump a message + * @param src identifies source of the message, never <code>null</code> + * @param severity one of predefined levels + * @param format message format suitable for {@link String#format(String, Object...)}, never <code>null</code> + * @param args optional arguments for the preceding format argument, may be <code>null</code> + */ + void dump(Class<?> src, Severity severity, String format, Object... args); + + /** + * Alternative to dump an exception + * + * @param src identifies source of the message, never <code>null</code> + * @param severity one of predefined levels + * @param th original exception, never <code>null</code> + * @param message additional description of the error/conditions, may be <code>null</code> + */ + void dump(Class<?> src, Severity severity, Throwable th, String message); }
--- a/src/org/tmatesoft/hg/util/Outcome.java Wed Jun 13 21:07:39 2012 +0200 +++ b/src/org/tmatesoft/hg/util/Outcome.java Mon Jun 18 16:54:00 2012 +0200 @@ -22,7 +22,7 @@ * @author Artem Tikhomirov * @author TMate Software Ltd. */ -public class Outcome { +public final class Outcome { // XXX perhaps private enum and factory method createError() and createOk()? public enum Kind { Success, Failure;
--- a/src/org/tmatesoft/hg/util/RegularFileInfo.java Wed Jun 13 21:07:39 2012 +0200 +++ b/src/org/tmatesoft/hg/util/RegularFileInfo.java Mon Jun 18 16:54:00 2012 +0200 @@ -16,6 +16,8 @@ */ package org.tmatesoft.hg.util; +import static org.tmatesoft.hg.util.LogFacility.Severity.Info; + import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; @@ -85,7 +87,7 @@ return new FileInputStream(file).getChannel(); } } catch (FileNotFoundException ex) { - StreamLogFacility.newDefault().debug(getClass(), ex, null); + StreamLogFacility.newDefault().dump(getClass(), Info, ex, null); // shall not happen, provided this class is used correctly return new ByteArrayReadableChannel(null); }
--- a/src/org/tmatesoft/hg/util/RegularFileStats.java Wed Jun 13 21:07:39 2012 +0200 +++ b/src/org/tmatesoft/hg/util/RegularFileStats.java Mon Jun 18 16:54:00 2012 +0200 @@ -16,6 +16,8 @@ */ package org.tmatesoft.hg.util; +import static org.tmatesoft.hg.util.LogFacility.Severity.Warn; + import java.io.File; import java.io.IOException; import java.util.ArrayList; @@ -140,11 +142,11 @@ symlinkValue = null; } } catch (InterruptedException ex) { - sessionContext.getLog().warn(getClass(), ex, String.format("Failed to detect flags for %s", f)); + sessionContext.getLog().dump(getClass(), Warn, ex, String.format("Failed to detect flags for %s", f)); // try again? ensure not too long? stop right away? // IGNORE, keep isExec and isSymlink false } catch (IOException ex) { - sessionContext.getLog().warn(getClass(), ex, String.format("Failed to detect flags for %s", f)); + sessionContext.getLog().dump(getClass(), Warn, ex, String.format("Failed to detect flags for %s", f)); // IGNORE, keep isExec and isSymlink false } }