You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by se...@apache.org on 2008/05/21 01:48:51 UTC
svn commit: r658491 [2/3] - in /commons/proper/net/trunk/src:
java/examples/nntp/ java/examples/ntp/ java/org/apache/commons/net/ftp/
java/org/apache/commons/net/ftp/parser/ java/org/apache/commons/net/nntp/
java/org/apache/commons/net/ntp/ java/org/ap...
Modified: commons/proper/net/trunk/src/java/org/apache/commons/net/ftp/parser/FTPTimestampParserImpl.java
URL: http://svn.apache.org/viewvc/commons/proper/net/trunk/src/java/org/apache/commons/net/ftp/parser/FTPTimestampParserImpl.java?rev=658491&r1=658490&r2=658491&view=diff
==============================================================================
--- commons/proper/net/trunk/src/java/org/apache/commons/net/ftp/parser/FTPTimestampParserImpl.java (original)
+++ commons/proper/net/trunk/src/java/org/apache/commons/net/ftp/parser/FTPTimestampParserImpl.java Tue May 20 16:48:50 2008
@@ -37,70 +37,70 @@
* @since 1.4
*/
public class FTPTimestampParserImpl implements
- FTPTimestampParser, Configurable
+ FTPTimestampParser, Configurable
{
-
- private SimpleDateFormat defaultDateFormat;
- private SimpleDateFormat recentDateFormat;
- private boolean lenientFutureDates = false;
-
-
- /**
- * The only constructor for this class.
- */
- public FTPTimestampParserImpl() {
- setDefaultDateFormat(DEFAULT_SDF);
- setRecentDateFormat(DEFAULT_RECENT_SDF);
- }
-
- /**
- * Implements the one {@link FTPTimestampParser#parseTimestamp(String) method}
- * in the {@link FTPTimestampParser FTPTimestampParser} interface
- * according to this algorithm:
- *
- * If the recentDateFormat member has been defined, try to parse the
- * supplied string with that. If that parse fails, or if the recentDateFormat
- * member has not been defined, attempt to parse with the defaultDateFormat
- * member. If that fails, throw a ParseException.
- *
- * This method allows a {@link Calendar} instance to be passed in which represents the
- * current (system) time.
- *
- * @see org.apache.commons.net.ftp.parser.FTPTimestampParser#parseTimestamp(java.lang.String)
- *
- * @param timestampStr The timestamp to be parsed
- */
- public Calendar parseTimestamp(String timestampStr) throws ParseException {
- Calendar now = Calendar.getInstance();
- return parseTimestamp(timestampStr, now);
- }
-
- /**
- * Implements the one {@link FTPTimestampParser#parseTimestamp(String) method}
- * in the {@link FTPTimestampParser FTPTimestampParser} interface
- * according to this algorithm:
- *
- * If the recentDateFormat member has been defined, try to parse the
- * supplied string with that. If that parse fails, or if the recentDateFormat
- * member has not been defined, attempt to parse with the defaultDateFormat
- * member. If that fails, throw a ParseException.
- *
- * @see org.apache.commons.net.ftp.parser.FTPTimestampParser#parseTimestamp(java.lang.String)
- * @param timestampStr The timestamp to be parsed
- * @param serverTime The current time for the server
- * @since 1.5
- */
- public Calendar parseTimestamp(String timestampStr, Calendar serverTime) throws ParseException {
- Calendar now = (Calendar) serverTime.clone();// Copy this, because we may change it
- now.setTimeZone(this.getServerTimeZone());
- Calendar working = (Calendar) now.clone();
- working.setTimeZone(getServerTimeZone());
- ParsePosition pp = new ParsePosition(0);
+
+ private SimpleDateFormat defaultDateFormat;
+ private SimpleDateFormat recentDateFormat;
+ private boolean lenientFutureDates = false;
+
+
+ /**
+ * The only constructor for this class.
+ */
+ public FTPTimestampParserImpl() {
+ setDefaultDateFormat(DEFAULT_SDF);
+ setRecentDateFormat(DEFAULT_RECENT_SDF);
+ }
+
+ /**
+ * Implements the one {@link FTPTimestampParser#parseTimestamp(String) method}
+ * in the {@link FTPTimestampParser FTPTimestampParser} interface
+ * according to this algorithm:
+ *
+ * If the recentDateFormat member has been defined, try to parse the
+ * supplied string with that. If that parse fails, or if the recentDateFormat
+ * member has not been defined, attempt to parse with the defaultDateFormat
+ * member. If that fails, throw a ParseException.
+ *
+ * This method allows a {@link Calendar} instance to be passed in which represents the
+ * current (system) time.
+ *
+ * @see org.apache.commons.net.ftp.parser.FTPTimestampParser#parseTimestamp(java.lang.String)
+ *
+ * @param timestampStr The timestamp to be parsed
+ */
+ public Calendar parseTimestamp(String timestampStr) throws ParseException {
+ Calendar now = Calendar.getInstance();
+ return parseTimestamp(timestampStr, now);
+ }
+
+ /**
+ * Implements the one {@link FTPTimestampParser#parseTimestamp(String) method}
+ * in the {@link FTPTimestampParser FTPTimestampParser} interface
+ * according to this algorithm:
+ *
+ * If the recentDateFormat member has been defined, try to parse the
+ * supplied string with that. If that parse fails, or if the recentDateFormat
+ * member has not been defined, attempt to parse with the defaultDateFormat
+ * member. If that fails, throw a ParseException.
+ *
+ * @see org.apache.commons.net.ftp.parser.FTPTimestampParser#parseTimestamp(java.lang.String)
+ * @param timestampStr The timestamp to be parsed
+ * @param serverTime The current time for the server
+ * @since 1.5
+ */
+ public Calendar parseTimestamp(String timestampStr, Calendar serverTime) throws ParseException {
+ Calendar now = (Calendar) serverTime.clone();// Copy this, because we may change it
+ now.setTimeZone(this.getServerTimeZone());
+ Calendar working = (Calendar) now.clone();
+ working.setTimeZone(getServerTimeZone());
+ ParsePosition pp = new ParsePosition(0);
- Date parsed = null;
- String timeStampStrPlusYear="";
- if (recentDateFormat != null) {
+ Date parsed = null;
+ String timeStampStrPlusYear="";
+ if (recentDateFormat != null) {
if (lenientFutureDates) {
// add a day to "now" so that "slop" doesn't cause a date
// slightly in the future to roll back a full year. (Bug 35181)
@@ -118,165 +118,165 @@
hackFormatter.setLenient(false);
hackFormatter.setTimeZone(recentDateFormat.getTimeZone());
parsed = hackFormatter.parse(timeStampStrPlusYear, pp);
- }
- if (parsed != null && pp.getIndex() == timeStampStrPlusYear.length())
- {
- working.setTime(parsed);
+ }
+ if (parsed != null && pp.getIndex() == timeStampStrPlusYear.length())
+ {
+ working.setTime(parsed);
- if (working.after(now)) {
- working.add(Calendar.YEAR, -1);
- }
- } else {
- pp = new ParsePosition(0);
- parsed = defaultDateFormat.parse(timestampStr, pp);
- // note, length checks are mandatory for us since
- // SimpleDateFormat methods will succeed if less than
- // full string is matched. They will also accept,
- // despite "leniency" setting, a two-digit number as
- // a valid year (e.g. 22:04 will parse as 22 A.D.)
- // so could mistakenly confuse an hour with a year,
- // if we don't insist on full length parsing.
- if (parsed != null && pp.getIndex() == timestampStr.length()) {
- working.setTime(parsed);
- } else {
- throw new ParseException(
- "Timestamp could not be parsed with older or recent DateFormat",
- pp.getIndex());
- }
- }
- return working;
- }
+ if (working.after(now)) {
+ working.add(Calendar.YEAR, -1);
+ }
+ } else {
+ pp = new ParsePosition(0);
+ parsed = defaultDateFormat.parse(timestampStr, pp);
+ // note, length checks are mandatory for us since
+ // SimpleDateFormat methods will succeed if less than
+ // full string is matched. They will also accept,
+ // despite "leniency" setting, a two-digit number as
+ // a valid year (e.g. 22:04 will parse as 22 A.D.)
+ // so could mistakenly confuse an hour with a year,
+ // if we don't insist on full length parsing.
+ if (parsed != null && pp.getIndex() == timestampStr.length()) {
+ working.setTime(parsed);
+ } else {
+ throw new ParseException(
+ "Timestamp could not be parsed with older or recent DateFormat",
+ pp.getIndex());
+ }
+ }
+ return working;
+ }
- /**
- * @return Returns the defaultDateFormat.
- */
- public SimpleDateFormat getDefaultDateFormat() {
- return defaultDateFormat;
- }
- /**
- * @return Returns the defaultDateFormat pattern string.
- */
- public String getDefaultDateFormatString() {
- return defaultDateFormat.toPattern();
- }
- /**
- * @param defaultDateFormat The defaultDateFormat to be set.
- */
- private void setDefaultDateFormat(String format) {
- if (format != null) {
- this.defaultDateFormat = new SimpleDateFormat(format);
- this.defaultDateFormat.setLenient(false);
- }
- }
- /**
- * @return Returns the recentDateFormat.
- */
- public SimpleDateFormat getRecentDateFormat() {
- return recentDateFormat;
- }
- /**
- * @return Returns the recentDateFormat.
- */
- public String getRecentDateFormatString() {
- return recentDateFormat.toPattern();
- }
- /**
- * @param recentDateFormat The recentDateFormat to set.
- */
- private void setRecentDateFormat(String format) {
- if (format != null) {
- this.recentDateFormat = new SimpleDateFormat(format);
- this.recentDateFormat.setLenient(false);
- }
- }
-
- /**
- * @return returns an array of 12 strings representing the short
- * month names used by this parse.
- */
- public String[] getShortMonths() {
- return defaultDateFormat.getDateFormatSymbols().getShortMonths();
- }
-
-
- /**
- * @return Returns the serverTimeZone used by this parser.
- */
- public TimeZone getServerTimeZone() {
- return this.defaultDateFormat.getTimeZone();
- }
- /**
- * sets a TimeZone represented by the supplied ID string into all
- * of the parsers used by this server.
- * @param serverTimeZone Time Id java.util.TimeZone id used by
- * the ftp server. If null the client's local time zone is assumed.
- */
- private void setServerTimeZone(String serverTimeZoneId) {
- TimeZone serverTimeZone = TimeZone.getDefault();
- if (serverTimeZoneId != null) {
- serverTimeZone = TimeZone.getTimeZone(serverTimeZoneId);
- }
- this.defaultDateFormat.setTimeZone(serverTimeZone);
- if (this.recentDateFormat != null) {
- this.recentDateFormat.setTimeZone(serverTimeZone);
- }
- }
-
- /**
- * Implementation of the {@link Configurable Configurable}
- * interface. Configures this <code>FTPTimestampParser</code> according
- * to the following logic:
- * <p>
- * Set up the {@link FTPClientConfig#setDefaultDateFormatStr(java.lang.String) defaultDateFormat}
- * and optionally the {@link FTPClientConfig#setRecentDateFormatStr(String) recentDateFormat}
- * to values supplied in the config based on month names configured as follows:
- * </p><p><ul>
- * <li>If a {@link FTPClientConfig#setShortMonthNames(String) shortMonthString}
- * has been supplied in the <code>config</code>, use that to parse parse timestamps.</li>
- * <li>Otherwise, if a {@link FTPClientConfig#setServerLanguageCode(String) serverLanguageCode}
- * has been supplied in the <code>config</code>, use the month names represented
- * by that {@link FTPClientConfig#lookupDateFormatSymbols(String) language}
- * to parse timestamps.</li>
- * <li>otherwise use default English month names</li>
- * </ul></p><p>
- * Finally if a {@link org.apache.commons.net.ftp.FTPClientConfig#setServerTimeZoneId(String) serverTimeZoneId}
- * has been supplied via the config, set that into all date formats that have
- * been configured.
- * </p>
- */
- public void configure(FTPClientConfig config) {
- DateFormatSymbols dfs = null;
-
- String languageCode = config.getServerLanguageCode();
- String shortmonths = config.getShortMonthNames();
- if (shortmonths != null) {
- dfs = FTPClientConfig.getDateFormatSymbols(shortmonths);
- } else if (languageCode != null) {
- dfs = FTPClientConfig.lookupDateFormatSymbols(languageCode);
- } else {
- dfs = FTPClientConfig.lookupDateFormatSymbols("en");
- }
-
-
- String recentFormatString = config.getRecentDateFormatStr();
- if (recentFormatString == null) {
- this.recentDateFormat = null;
- } else {
- this.recentDateFormat = new SimpleDateFormat(recentFormatString, dfs);
- this.recentDateFormat.setLenient(false);
- }
-
- String defaultFormatString = config.getDefaultDateFormatStr();
- if (defaultFormatString == null) {
- throw new IllegalArgumentException("defaultFormatString cannot be null");
- }
- this.defaultDateFormat = new SimpleDateFormat(defaultFormatString, dfs);
- this.defaultDateFormat.setLenient(false);
-
- setServerTimeZone(config.getServerTimeZoneId());
-
- this.lenientFutureDates = config.isLenientFutureDates();
- }
+ /**
+ * @return Returns the defaultDateFormat.
+ */
+ public SimpleDateFormat getDefaultDateFormat() {
+ return defaultDateFormat;
+ }
+ /**
+ * @return Returns the defaultDateFormat pattern string.
+ */
+ public String getDefaultDateFormatString() {
+ return defaultDateFormat.toPattern();
+ }
+ /**
+ * @param defaultDateFormat The defaultDateFormat to be set.
+ */
+ private void setDefaultDateFormat(String format) {
+ if (format != null) {
+ this.defaultDateFormat = new SimpleDateFormat(format);
+ this.defaultDateFormat.setLenient(false);
+ }
+ }
+ /**
+ * @return Returns the recentDateFormat.
+ */
+ public SimpleDateFormat getRecentDateFormat() {
+ return recentDateFormat;
+ }
+ /**
+ * @return Returns the recentDateFormat.
+ */
+ public String getRecentDateFormatString() {
+ return recentDateFormat.toPattern();
+ }
+ /**
+ * @param recentDateFormat The recentDateFormat to set.
+ */
+ private void setRecentDateFormat(String format) {
+ if (format != null) {
+ this.recentDateFormat = new SimpleDateFormat(format);
+ this.recentDateFormat.setLenient(false);
+ }
+ }
+
+ /**
+ * @return returns an array of 12 strings representing the short
+ * month names used by this parse.
+ */
+ public String[] getShortMonths() {
+ return defaultDateFormat.getDateFormatSymbols().getShortMonths();
+ }
+
+
+ /**
+ * @return Returns the serverTimeZone used by this parser.
+ */
+ public TimeZone getServerTimeZone() {
+ return this.defaultDateFormat.getTimeZone();
+ }
+ /**
+ * sets a TimeZone represented by the supplied ID string into all
+ * of the parsers used by this server.
+ * @param serverTimeZone Time Id java.util.TimeZone id used by
+ * the ftp server. If null the client's local time zone is assumed.
+ */
+ private void setServerTimeZone(String serverTimeZoneId) {
+ TimeZone serverTimeZone = TimeZone.getDefault();
+ if (serverTimeZoneId != null) {
+ serverTimeZone = TimeZone.getTimeZone(serverTimeZoneId);
+ }
+ this.defaultDateFormat.setTimeZone(serverTimeZone);
+ if (this.recentDateFormat != null) {
+ this.recentDateFormat.setTimeZone(serverTimeZone);
+ }
+ }
+
+ /**
+ * Implementation of the {@link Configurable Configurable}
+ * interface. Configures this <code>FTPTimestampParser</code> according
+ * to the following logic:
+ * <p>
+ * Set up the {@link FTPClientConfig#setDefaultDateFormatStr(java.lang.String) defaultDateFormat}
+ * and optionally the {@link FTPClientConfig#setRecentDateFormatStr(String) recentDateFormat}
+ * to values supplied in the config based on month names configured as follows:
+ * </p><p><ul>
+ * <li>If a {@link FTPClientConfig#setShortMonthNames(String) shortMonthString}
+ * has been supplied in the <code>config</code>, use that to parse parse timestamps.</li>
+ * <li>Otherwise, if a {@link FTPClientConfig#setServerLanguageCode(String) serverLanguageCode}
+ * has been supplied in the <code>config</code>, use the month names represented
+ * by that {@link FTPClientConfig#lookupDateFormatSymbols(String) language}
+ * to parse timestamps.</li>
+ * <li>otherwise use default English month names</li>
+ * </ul></p><p>
+ * Finally if a {@link org.apache.commons.net.ftp.FTPClientConfig#setServerTimeZoneId(String) serverTimeZoneId}
+ * has been supplied via the config, set that into all date formats that have
+ * been configured.
+ * </p>
+ */
+ public void configure(FTPClientConfig config) {
+ DateFormatSymbols dfs = null;
+
+ String languageCode = config.getServerLanguageCode();
+ String shortmonths = config.getShortMonthNames();
+ if (shortmonths != null) {
+ dfs = FTPClientConfig.getDateFormatSymbols(shortmonths);
+ } else if (languageCode != null) {
+ dfs = FTPClientConfig.lookupDateFormatSymbols(languageCode);
+ } else {
+ dfs = FTPClientConfig.lookupDateFormatSymbols("en");
+ }
+
+
+ String recentFormatString = config.getRecentDateFormatStr();
+ if (recentFormatString == null) {
+ this.recentDateFormat = null;
+ } else {
+ this.recentDateFormat = new SimpleDateFormat(recentFormatString, dfs);
+ this.recentDateFormat.setLenient(false);
+ }
+
+ String defaultFormatString = config.getDefaultDateFormatStr();
+ if (defaultFormatString == null) {
+ throw new IllegalArgumentException("defaultFormatString cannot be null");
+ }
+ this.defaultDateFormat = new SimpleDateFormat(defaultFormatString, dfs);
+ this.defaultDateFormat.setLenient(false);
+
+ setServerTimeZone(config.getServerTimeZoneId());
+
+ this.lenientFutureDates = config.isLenientFutureDates();
+ }
/**
* @return Returns the lenientFutureDates.
*/
Modified: commons/proper/net/trunk/src/java/org/apache/commons/net/ftp/parser/MVSFTPEntryParser.java
URL: http://svn.apache.org/viewvc/commons/proper/net/trunk/src/java/org/apache/commons/net/ftp/parser/MVSFTPEntryParser.java?rev=658491&r1=658490&r2=658491&view=diff
==============================================================================
--- commons/proper/net/trunk/src/java/org/apache/commons/net/ftp/parser/MVSFTPEntryParser.java (original)
+++ commons/proper/net/trunk/src/java/org/apache/commons/net/ftp/parser/MVSFTPEntryParser.java Tue May 20 16:48:50 2008
@@ -32,8 +32,8 @@
/**
* This is the regular expression used by this parser.
*/
- private static final String REGEX = "(.*)\\s+([^\\s]+)\\s*";
-
+ private static final String REGEX = "(.*)\\s+([^\\s]+)\\s*";
+
/**
* Although this parser is now ignoring dates, someone may someday
* figure out a way to accomodate this and this appears to be the
@@ -41,32 +41,32 @@
* SMC 2005/04/08
*/
static final String DEFAULT_DATE_FORMAT
- = "yyyy/MM/dd"; // 2001/11/09
+ = "yyyy/MM/dd"; // 2001/11/09
- // This is not at all the tightest possible regexp for MVS LIST
- // output, but I'm not a mainframe guru so I have little idea what the
- // range of valid values are. I just needed to get the filename (Dsname);
- // note that no other FTPFile fields can be filled in with the results of
- // a LIST on MVS. The 'Referred' date seems to be 'last accessed date'
- // and not 'last modified date' so I didn't bother parsing it.
- //
- // Of course it works perfectly as-is and it distinguishes header lines from
- // file results so that's the important thing.
- //
- // This parser should be used when SYST returns:
- // 'MVS is the operating system of this server. FTP Server is running on z/OS.'
- //
- // Also note that there is no concept of directories in MVS, just datasets,
- // which have names composed of four dot separated names of up to 8 chars.
- // As a result, FTPFile.FILE_TYPE is always used. -JN 6/2004 jnadler<at>srcginc<dotcom>
-
- // Sample LIST results from MVS:
- //
- //Volume Unit Referred Ext Used Recfm Lrecl BlkSz Dsorg Dsname
- //FPFS42 3390 2004/06/23 1 1 FB 128 6144 PS INCOMING.RPTBM023.D061704
- //FPFS41 3390 2004/06/23 1 1 FB 128 6144 PS INCOMING.RPTBM056.D061704
- //FPFS25 3390 2004/06/23 1 1 FB 128 6144 PS INCOMING.WTM204.D061704
+ // This is not at all the tightest possible regexp for MVS LIST
+ // output, but I'm not a mainframe guru so I have little idea what the
+ // range of valid values are. I just needed to get the filename (Dsname);
+ // note that no other FTPFile fields can be filled in with the results of
+ // a LIST on MVS. The 'Referred' date seems to be 'last accessed date'
+ // and not 'last modified date' so I didn't bother parsing it.
+ //
+ // Of course it works perfectly as-is and it distinguishes header lines from
+ // file results so that's the important thing.
+ //
+ // This parser should be used when SYST returns:
+ // 'MVS is the operating system of this server. FTP Server is running on z/OS.'
+ //
+ // Also note that there is no concept of directories in MVS, just datasets,
+ // which have names composed of four dot separated names of up to 8 chars.
+ // As a result, FTPFile.FILE_TYPE is always used. -JN 6/2004 jnadler<at>srcginc<dotcom>
+
+ // Sample LIST results from MVS:
+ //
+ //Volume Unit Referred Ext Used Recfm Lrecl BlkSz Dsorg Dsname
+ //FPFS42 3390 2004/06/23 1 1 FB 128 6144 PS INCOMING.RPTBM023.D061704
+ //FPFS41 3390 2004/06/23 1 1 FB 128 6144 PS INCOMING.RPTBM056.D061704
+ //FPFS25 3390 2004/06/23 1 1 FB 128 6144 PS INCOMING.WTM204.D061704
/**
* The sole constructor for a MVSFTPEntryParser object.
@@ -99,9 +99,9 @@
f = new FTPFile();
String dataSetName = group(2);
f.setType(FTPFile.FILE_TYPE);
- f.setName(dataSetName);
+ f.setName(dataSetName);
- return (f);
+ return (f);
}
return null;
}
Modified: commons/proper/net/trunk/src/java/org/apache/commons/net/ftp/parser/NTFTPEntryParser.java
URL: http://svn.apache.org/viewvc/commons/proper/net/trunk/src/java/org/apache/commons/net/ftp/parser/NTFTPEntryParser.java?rev=658491&r1=658490&r2=658491&view=diff
==============================================================================
--- commons/proper/net/trunk/src/java/org/apache/commons/net/ftp/parser/NTFTPEntryParser.java (original)
+++ commons/proper/net/trunk/src/java/org/apache/commons/net/ftp/parser/NTFTPEntryParser.java Tue May 20 16:48:50 2008
@@ -30,9 +30,9 @@
*/
public class NTFTPEntryParser extends ConfigurableFTPFileEntryParserImpl
{
-
+
private static final String DEFAULT_DATE_FORMAT
- = "MM-dd-yy hh:mma"; //11-09-01 12:30PM
+ = "MM-dd-yy hh:mma"; //11-09-01 12:30PM
/**
@@ -91,7 +91,7 @@
if (matches(entry))
{
- String datestr = group(1)+" "+group(2);
+ String datestr = group(1)+" "+group(2);
String dirString = group(3);
String size = group(4);
String name = group(5);
Modified: commons/proper/net/trunk/src/java/org/apache/commons/net/ftp/parser/NetwareFTPEntryParser.java
URL: http://svn.apache.org/viewvc/commons/proper/net/trunk/src/java/org/apache/commons/net/ftp/parser/NetwareFTPEntryParser.java?rev=658491&r1=658490&r2=658491&view=diff
==============================================================================
--- commons/proper/net/trunk/src/java/org/apache/commons/net/ftp/parser/NetwareFTPEntryParser.java (original)
+++ commons/proper/net/trunk/src/java/org/apache/commons/net/ftp/parser/NetwareFTPEntryParser.java Tue May 20 16:48:50 2008
@@ -34,141 +34,141 @@
*/
public class NetwareFTPEntryParser extends ConfigurableFTPFileEntryParserImpl {
- /**
- * Default date format is e.g. Feb 22 2006
- */
- private static final String DEFAULT_DATE_FORMAT = "MMM dd yyyy";
-
- /**
- * Default recent date format is e.g. Feb 22 17:32
- */
- private static final String DEFAULT_RECENT_DATE_FORMAT = "MMM dd HH:mm";
-
- /**
- * this is the regular expression used by this parser.
- * Example: d [-W---F--] SCION_VOL2 512 Apr 13 23:12 VOL2
- */
- private static final String REGEX = "(d|-){1}\\s+" // Directory/file flag
- + "\\[(.*)\\]\\s+" // Attributes
- + "(\\S+)\\s+" + "(\\d+)\\s+" // Owner and size
- + "(\\S+\\s+\\S+\\s+((\\d+:\\d+)|(\\d{4})))" // Long/short date format
- + "\\s+(.*)"; // Filename (incl. spaces)
-
- /**
- * The default constructor for a NetwareFTPEntryParser object.
- *
- * @exception IllegalArgumentException
- * Thrown if the regular expression is unparseable. Should not be seen
- * under normal conditions. It it is seen, this is a sign that
- * <code>REGEX</code> is not a valid regular expression.
- */
- public NetwareFTPEntryParser() {
- this(null);
- }
-
- /**
- * This constructor allows the creation of an NetwareFTPEntryParser object
- * with something other than the default configuration.
- *
- * @param config The {@link FTPClientConfig configuration} object used to
- * configure this parser.
- * @exception IllegalArgumentException
- * Thrown if the regular expression is unparseable. Should not be seen
- * under normal conditions. It it is seen, this is a sign that
- * <code>REGEX</code> is not a valid regular expression.
- * @since 1.4
- */
- public NetwareFTPEntryParser(FTPClientConfig config) {
- super(REGEX);
- configure(config);
- }
-
- /**
- * Parses a line of an NetwareFTP server file listing and converts it into a
- * usable format in the form of an <code> FTPFile </code> instance. If the
- * file listing line doesn't describe a file, <code> null </code> is
- * returned, otherwise a <code> FTPFile </code> instance representing the
- * files in the directory is returned.
- * <p>
- * <p>
- * Netware file permissions are in the following format: RWCEAFMS, and are explained as follows:
- * <ul>
- * <li><b>S</b> - Supervisor; All rights.
- * <li><b>R</b> - Read; Right to open and read or execute.
- * <li><b>W</b> - Write; Right to open and modify.
- * <li><b>C</b> - Create; Right to create; when assigned to a file, allows a deleted file to be recovered.
- * <li><b>E</b> - Erase; Right to delete.
- * <li><b>M</b> - Modify; Right to rename a file and to change attributes.
- * <li><b>F</b> - File Scan; Right to see directory or file listings.
- * <li><b>A</b> - Access Control; Right to modify trustee assignments and the Inherited Rights Mask.
- * </ul>
- *
- * See <a href="http://www.novell.com/documentation/nfap10/index.html?page=/documentation/nfap10/nfaubook/data/abxraws.html">here</a>
- * for more details
- *
- * @param entry A line of text from the file listing
- * @return An FTPFile instance corresponding to the supplied entry
- */
- public FTPFile parseFTPEntry(String entry) {
-
- FTPFile f = new FTPFile();
- if (matches(entry)) {
- String dirString = group(1);
- String attrib = group(2);
- String user = group(3);
- String size = group(4);
- String datestr = group(5);
- String name = group(9);
-
- try {
- f.setTimestamp(super.parseTimestamp(datestr));
- } catch (ParseException e) {
- // intentionally do nothing
- }
-
- //is it a DIR or a file
- if (dirString.trim().equals("d")) {
- f.setType(FTPFile.DIRECTORY_TYPE);
- } else // Should be "-"
- {
- f.setType(FTPFile.FILE_TYPE);
- }
-
- f.setUser(user);
-
- //set the name
- f.setName(name.trim());
-
- //set the size
- f.setSize(Long.parseLong(size.trim()));
-
- // Now set the permissions (or at least a subset thereof - full permissions would probably require
- // subclassing FTPFile and adding extra metainformation there)
- if (attrib.indexOf("R") != -1) {
- f.setPermission(FTPFile.USER_ACCESS, FTPFile.READ_PERMISSION,
- true);
- }
- if (attrib.indexOf("W") != -1) {
- f.setPermission(FTPFile.USER_ACCESS, FTPFile.WRITE_PERMISSION,
- true);
- }
-
- return (f);
- }
- return null;
-
- }
-
- /**
- * Defines a default configuration to be used when this class is
- * instantiated without a {@link FTPClientConfig FTPClientConfig}
- * parameter being specified.
- * @return the default configuration for this parser.
- */
- protected FTPClientConfig getDefaultConfiguration() {
- return new FTPClientConfig(FTPClientConfig.SYST_NETWARE,
- DEFAULT_DATE_FORMAT, DEFAULT_RECENT_DATE_FORMAT, null, null,
- null);
- }
+ /**
+ * Default date format is e.g. Feb 22 2006
+ */
+ private static final String DEFAULT_DATE_FORMAT = "MMM dd yyyy";
+
+ /**
+ * Default recent date format is e.g. Feb 22 17:32
+ */
+ private static final String DEFAULT_RECENT_DATE_FORMAT = "MMM dd HH:mm";
+
+ /**
+ * this is the regular expression used by this parser.
+ * Example: d [-W---F--] SCION_VOL2 512 Apr 13 23:12 VOL2
+ */
+ private static final String REGEX = "(d|-){1}\\s+" // Directory/file flag
+ + "\\[(.*)\\]\\s+" // Attributes
+ + "(\\S+)\\s+" + "(\\d+)\\s+" // Owner and size
+ + "(\\S+\\s+\\S+\\s+((\\d+:\\d+)|(\\d{4})))" // Long/short date format
+ + "\\s+(.*)"; // Filename (incl. spaces)
+
+ /**
+ * The default constructor for a NetwareFTPEntryParser object.
+ *
+ * @exception IllegalArgumentException
+ * Thrown if the regular expression is unparseable. Should not be seen
+ * under normal conditions. It it is seen, this is a sign that
+ * <code>REGEX</code> is not a valid regular expression.
+ */
+ public NetwareFTPEntryParser() {
+ this(null);
+ }
+
+ /**
+ * This constructor allows the creation of an NetwareFTPEntryParser object
+ * with something other than the default configuration.
+ *
+ * @param config The {@link FTPClientConfig configuration} object used to
+ * configure this parser.
+ * @exception IllegalArgumentException
+ * Thrown if the regular expression is unparseable. Should not be seen
+ * under normal conditions. It it is seen, this is a sign that
+ * <code>REGEX</code> is not a valid regular expression.
+ * @since 1.4
+ */
+ public NetwareFTPEntryParser(FTPClientConfig config) {
+ super(REGEX);
+ configure(config);
+ }
+
+ /**
+ * Parses a line of an NetwareFTP server file listing and converts it into a
+ * usable format in the form of an <code> FTPFile </code> instance. If the
+ * file listing line doesn't describe a file, <code> null </code> is
+ * returned, otherwise a <code> FTPFile </code> instance representing the
+ * files in the directory is returned.
+ * <p>
+ * <p>
+ * Netware file permissions are in the following format: RWCEAFMS, and are explained as follows:
+ * <ul>
+ * <li><b>S</b> - Supervisor; All rights.
+ * <li><b>R</b> - Read; Right to open and read or execute.
+ * <li><b>W</b> - Write; Right to open and modify.
+ * <li><b>C</b> - Create; Right to create; when assigned to a file, allows a deleted file to be recovered.
+ * <li><b>E</b> - Erase; Right to delete.
+ * <li><b>M</b> - Modify; Right to rename a file and to change attributes.
+ * <li><b>F</b> - File Scan; Right to see directory or file listings.
+ * <li><b>A</b> - Access Control; Right to modify trustee assignments and the Inherited Rights Mask.
+ * </ul>
+ *
+ * See <a href="http://www.novell.com/documentation/nfap10/index.html?page=/documentation/nfap10/nfaubook/data/abxraws.html">here</a>
+ * for more details
+ *
+ * @param entry A line of text from the file listing
+ * @return An FTPFile instance corresponding to the supplied entry
+ */
+ public FTPFile parseFTPEntry(String entry) {
+
+ FTPFile f = new FTPFile();
+ if (matches(entry)) {
+ String dirString = group(1);
+ String attrib = group(2);
+ String user = group(3);
+ String size = group(4);
+ String datestr = group(5);
+ String name = group(9);
+
+ try {
+ f.setTimestamp(super.parseTimestamp(datestr));
+ } catch (ParseException e) {
+ // intentionally do nothing
+ }
+
+ //is it a DIR or a file
+ if (dirString.trim().equals("d")) {
+ f.setType(FTPFile.DIRECTORY_TYPE);
+ } else // Should be "-"
+ {
+ f.setType(FTPFile.FILE_TYPE);
+ }
+
+ f.setUser(user);
+
+ //set the name
+ f.setName(name.trim());
+
+ //set the size
+ f.setSize(Long.parseLong(size.trim()));
+
+ // Now set the permissions (or at least a subset thereof - full permissions would probably require
+ // subclassing FTPFile and adding extra metainformation there)
+ if (attrib.indexOf("R") != -1) {
+ f.setPermission(FTPFile.USER_ACCESS, FTPFile.READ_PERMISSION,
+ true);
+ }
+ if (attrib.indexOf("W") != -1) {
+ f.setPermission(FTPFile.USER_ACCESS, FTPFile.WRITE_PERMISSION,
+ true);
+ }
+
+ return (f);
+ }
+ return null;
+
+ }
+
+ /**
+ * Defines a default configuration to be used when this class is
+ * instantiated without a {@link FTPClientConfig FTPClientConfig}
+ * parameter being specified.
+ * @return the default configuration for this parser.
+ */
+ protected FTPClientConfig getDefaultConfiguration() {
+ return new FTPClientConfig(FTPClientConfig.SYST_NETWARE,
+ DEFAULT_DATE_FORMAT, DEFAULT_RECENT_DATE_FORMAT, null, null,
+ null);
+ }
}
Modified: commons/proper/net/trunk/src/java/org/apache/commons/net/ftp/parser/OS2FTPEntryParser.java
URL: http://svn.apache.org/viewvc/commons/proper/net/trunk/src/java/org/apache/commons/net/ftp/parser/OS2FTPEntryParser.java?rev=658491&r1=658490&r2=658491&view=diff
==============================================================================
--- commons/proper/net/trunk/src/java/org/apache/commons/net/ftp/parser/OS2FTPEntryParser.java (original)
+++ commons/proper/net/trunk/src/java/org/apache/commons/net/ftp/parser/OS2FTPEntryParser.java Tue May 20 16:48:50 2008
@@ -31,9 +31,9 @@
public class OS2FTPEntryParser extends ConfigurableFTPFileEntryParserImpl
{
-
+
private static final String DEFAULT_DATE_FORMAT
- = "MM-dd-yy HH:mm"; //11-09-01 12:30
+ = "MM-dd-yy HH:mm"; //11-09-01 12:30
/**
* this is the regular expression used by this parser.
*/
@@ -94,7 +94,7 @@
String size = group(1);
String attrib = group(2);
String dirString = group(3);
- String datestr = group(4)+" "+group(5);
+ String datestr = group(4)+" "+group(5);
String name = group(6);
try
{
Modified: commons/proper/net/trunk/src/java/org/apache/commons/net/ftp/parser/OS400FTPEntryParser.java
URL: http://svn.apache.org/viewvc/commons/proper/net/trunk/src/java/org/apache/commons/net/ftp/parser/OS400FTPEntryParser.java?rev=658491&r1=658490&r2=658491&view=diff
==============================================================================
--- commons/proper/net/trunk/src/java/org/apache/commons/net/ftp/parser/OS400FTPEntryParser.java (original)
+++ commons/proper/net/trunk/src/java/org/apache/commons/net/ftp/parser/OS400FTPEntryParser.java Tue May 20 16:48:50 2008
@@ -28,11 +28,11 @@
public class OS400FTPEntryParser extends ConfigurableFTPFileEntryParserImpl
{
private static final String DEFAULT_DATE_FORMAT
- = "yy/MM/dd HH:mm:ss"; //01/11/09 12:30:24
+ = "yy/MM/dd HH:mm:ss"; //01/11/09 12:30:24
- private static final String REGEX =
+ private static final String REGEX =
"(\\S+)\\s+" // user
+ "(\\d+)\\s+" // size
+ "(\\S+)\\s+(\\S+)\\s+" // date stuff
@@ -83,7 +83,7 @@
{
String usr = group(1);
String filesize = group(2);
- String datestr = group(3)+" "+group(4);
+ String datestr = group(3)+" "+group(4);
String typeStr = group(5);
String name = group(6);
@@ -93,7 +93,7 @@
}
catch (ParseException e)
{
- // intentionally do nothing
+ // intentionally do nothing
}
Modified: commons/proper/net/trunk/src/java/org/apache/commons/net/ftp/parser/UnixFTPEntryParser.java
URL: http://svn.apache.org/viewvc/commons/proper/net/trunk/src/java/org/apache/commons/net/ftp/parser/UnixFTPEntryParser.java?rev=658491&r1=658490&r2=658491&view=diff
==============================================================================
--- commons/proper/net/trunk/src/java/org/apache/commons/net/ftp/parser/UnixFTPEntryParser.java (original)
+++ commons/proper/net/trunk/src/java/org/apache/commons/net/ftp/parser/UnixFTPEntryParser.java Tue May 20 16:48:50 2008
@@ -40,13 +40,13 @@
"(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)";
static final String DEFAULT_DATE_FORMAT
- = "MMM d yyyy"; //Nov 9 2001
+ = "MMM d yyyy"; //Nov 9 2001
static final String DEFAULT_RECENT_DATE_FORMAT
- = "MMM d HH:mm"; //Nov 9 20:06
+ = "MMM d HH:mm"; //Nov 9 20:06
static final String NUMERIC_DATE_FORMAT
- = "yyyy-MM-dd HH:mm"; //2001-11-09 20:06
+ = "yyyy-MM-dd HH:mm"; //2001-11-09 20:06
/**
* Some Linux distributions are now shipping an FTP server which formats
@@ -97,14 +97,14 @@
numeric or standard format date
*/
+ "((?:\\d+[-/]\\d+[-/]\\d+)|(?:\\S+\\s+\\S+))\\s+"
-
+
/*
year (for non-recent standard format)
- or time (for numeric or recent standard format
- */
- + "(\\d+(?::\\d+)?)\\s+"
+ or time (for numeric or recent standard format
+ */
+ + "(\\d+(?::\\d+)?)\\s+"
- + "(\\S*)(\\s*.*)";
+ + "(\\S*)(\\s*.*)";
/**
@@ -149,7 +149,7 @@
* @param entry A line of text from the file listing
* @return An FTPFile instance corresponding to the supplied entry
*/
- public FTPFile parseFTPEntry(String entry) {
+ public FTPFile parseFTPEntry(String entry) {
FTPFile file = new FTPFile();
file.setRawListing(entry);
int type;
@@ -191,8 +191,8 @@
// break; - fall through
case 'f':
case '-':
- type = FTPFile.FILE_TYPE;
- break;
+ type = FTPFile.FILE_TYPE;
+ break;
default:
type = FTPFile.UNKNOWN_TYPE;
}
@@ -276,7 +276,7 @@
return file;
}
return null;
- }
+ }
/**
* Defines a default configuration to be used when this class is
Modified: commons/proper/net/trunk/src/java/org/apache/commons/net/ftp/parser/VMSFTPEntryParser.java
URL: http://svn.apache.org/viewvc/commons/proper/net/trunk/src/java/org/apache/commons/net/ftp/parser/VMSFTPEntryParser.java?rev=658491&r1=658490&r2=658491&view=diff
==============================================================================
--- commons/proper/net/trunk/src/java/org/apache/commons/net/ftp/parser/VMSFTPEntryParser.java (original)
+++ commons/proper/net/trunk/src/java/org/apache/commons/net/ftp/parser/VMSFTPEntryParser.java Tue May 20 16:48:50 2008
@@ -51,7 +51,7 @@
{
private static final String DEFAULT_DATE_FORMAT
- = "d-MMM-yyyy HH:mm:ss"; //9-NOV-2001 12:30:24
+ = "d-MMM-yyyy HH:mm:ss"; //9-NOV-2001 12:30:24
/**
* this is the regular expression used by this parser.
@@ -142,10 +142,10 @@
f.setRawListing(entry);
String name = group(1);
String size = group(2);
- String datestr = group(3)+" "+group(4);
+ String datestr = group(3)+" "+group(4);
String owner = group(5);
- String permissions[] = new String[3];
- permissions[0]= group(9);
+ String permissions[] = new String[3];
+ permissions[0]= group(9);
permissions[1]= group(10);
permissions[2]= group(11);
try
Modified: commons/proper/net/trunk/src/java/org/apache/commons/net/nntp/Article.java
URL: http://svn.apache.org/viewvc/commons/proper/net/trunk/src/java/org/apache/commons/net/nntp/Article.java?rev=658491&r1=658490&r2=658491&view=diff
==============================================================================
--- commons/proper/net/trunk/src/java/org/apache/commons/net/nntp/Article.java (original)
+++ commons/proper/net/trunk/src/java/org/apache/commons/net/nntp/Article.java Tue May 20 16:48:50 2008
@@ -27,227 +27,227 @@
*
*/
public class Article implements Threadable {
- private int articleNumber;
- private String subject;
- private String date;
- private String articleId;
- private String simplifiedSubject;
- private String from;
- private StringBuffer header;
- private StringBuffer references;
- private boolean isReply = false;
-
- public Article kid, next;
-
- public Article() {
- header = new StringBuffer();
- }
-
- /**
- * Adds an arbitrary header key and value to this message's header.
- * @param name the header name
- * @param val the header value
- */
- public void addHeaderField(String name, String val) {
- header.append(name);
- header.append(": ");
- header.append(val);
- header.append('\n');
- }
-
- /**
- * Adds a message-id to the list of messages that this message references (i.e. replies to)
- * @param msgId
- */
- public void addReference(String msgId) {
- if (references == null) {
- references = new StringBuffer();
- references.append("References: ");
- }
- references.append(msgId);
- references.append("\t");
- }
-
- /**
- * Returns the MessageId references as an array of Strings
- * @return an array of message-ids
- */
- public String[] getReferences() {
- if (references == null)
- return new String[0];
- ArrayList list = new ArrayList();
- int terminator = references.toString().indexOf(':');
- StringTokenizer st =
- new StringTokenizer(references.substring(terminator), "\t");
- while (st.hasMoreTokens()) {
- list.add(st.nextToken());
- }
- return (String[]) list.toArray(new String[list.size()]);
- }
-
- /**
- * Attempts to parse the subject line for some typical reply signatures, and strip them out
- *
- */
- private void simplifySubject() {
- int start = 0;
- String subject = getSubject();
- int len = subject.length();
-
- boolean done = false;
-
- while (!done) {
- done = true;
-
- // skip whitespace
- // "Re: " breaks this
- while (start < len && subject.charAt(start) == ' ') {
- start++;
- }
-
- if (start < (len - 2)
- && (subject.charAt(start) == 'r' || subject.charAt(start) == 'R')
- && (subject.charAt(start + 1) == 'e' || subject.charAt(start + 1) == 'E')) {
-
- if (subject.charAt(start + 2) == ':') {
- start += 3; // Skip "Re:"
- isReply = true;
- done = false;
- } else if (
- start < (len - 2)
- &&
- (subject.charAt(start + 2) == '[' || subject.charAt(start + 2) == '(')) {
-
- int i = start + 3;
-
- while (i < len && subject.charAt(i) >= '0' && subject.charAt(i) <= '9')
- i++;
-
- if (i < (len - 1)
- && (subject.charAt(i) == ']' || subject.charAt(i) == ')')
- && subject.charAt(i + 1) == ':') {
- start = i + 2;
- isReply = true;
- done = false;
- }
- }
- }
-
- if (simplifiedSubject == "(no subject)")
- simplifiedSubject = "";
-
- int end = len;
-
- while (end > start && subject.charAt(end - 1) < ' ')
- end--;
-
- if (start == 0 && end == len)
- simplifiedSubject = subject;
- else
- simplifiedSubject = subject.substring(start, end);
- }
- }
-
- /**
- * Recursive method that traverses a pre-threaded graph (or tree)
- * of connected Article objects and prints them out.
- * @param article the root of the article 'tree'
- * @param depth the current tree depth
- */
- public static void printThread(Article article, int depth) {
- for (int i = 0; i < depth; ++i)
- System.out.print("==>");
- System.out.println(article.getSubject() + "\t" + article.getFrom());
- if (article.kid != null)
- printThread(article.kid, depth + 1);
- if (article.next != null)
- printThread(article.next, depth);
- }
-
- public String getArticleId() {
- return articleId;
- }
-
- public int getArticleNumber() {
- return articleNumber;
- }
-
- public String getDate() {
- return date;
- }
-
- public String getFrom() {
- return from;
- }
-
- public String getSubject() {
- return subject;
- }
-
- public void setArticleId(String string) {
- articleId = string;
- }
-
- public void setArticleNumber(int i) {
- articleNumber = i;
- }
-
- public void setDate(String string) {
- date = string;
- }
-
- public void setFrom(String string) {
- from = string;
- }
-
- public void setSubject(String string) {
- subject = string;
- }
-
-
- public boolean isDummy() {
- return (getSubject() == null);
- }
-
- public String messageThreadId() {
- return articleId;
- }
-
- public String[] messageThreadReferences() {
- return getReferences();
- }
-
- public String simplifiedSubject() {
- if(simplifiedSubject == null)
- simplifySubject();
- return simplifiedSubject;
- }
-
-
- public boolean subjectIsReply() {
- if(simplifiedSubject == null)
- simplifySubject();
- return isReply;
- }
-
-
- public void setChild(Threadable child) {
- this.kid = (Article) child;
- flushSubjectCache();
- }
-
- private void flushSubjectCache() {
- simplifiedSubject = null;
- }
-
-
- public void setNext(Threadable next) {
- this.next = (Article)next;
- flushSubjectCache();
- }
-
-
- public Threadable makeDummy() {
- return new Article();
- }
+ private int articleNumber;
+ private String subject;
+ private String date;
+ private String articleId;
+ private String simplifiedSubject;
+ private String from;
+ private StringBuffer header;
+ private StringBuffer references;
+ private boolean isReply = false;
+
+ public Article kid, next;
+
+ public Article() {
+ header = new StringBuffer();
+ }
+
+ /**
+ * Adds an arbitrary header key and value to this message's header.
+ * @param name the header name
+ * @param val the header value
+ */
+ public void addHeaderField(String name, String val) {
+ header.append(name);
+ header.append(": ");
+ header.append(val);
+ header.append('\n');
+ }
+
+ /**
+ * Adds a message-id to the list of messages that this message references (i.e. replies to)
+ * @param msgId
+ */
+ public void addReference(String msgId) {
+ if (references == null) {
+ references = new StringBuffer();
+ references.append("References: ");
+ }
+ references.append(msgId);
+ references.append("\t");
+ }
+
+ /**
+ * Returns the MessageId references as an array of Strings
+ * @return an array of message-ids
+ */
+ public String[] getReferences() {
+ if (references == null)
+ return new String[0];
+ ArrayList list = new ArrayList();
+ int terminator = references.toString().indexOf(':');
+ StringTokenizer st =
+ new StringTokenizer(references.substring(terminator), "\t");
+ while (st.hasMoreTokens()) {
+ list.add(st.nextToken());
+ }
+ return (String[]) list.toArray(new String[list.size()]);
+ }
+
+ /**
+ * Attempts to parse the subject line for some typical reply signatures, and strip them out
+ *
+ */
+ private void simplifySubject() {
+ int start = 0;
+ String subject = getSubject();
+ int len = subject.length();
+
+ boolean done = false;
+
+ while (!done) {
+ done = true;
+
+ // skip whitespace
+ // "Re: " breaks this
+ while (start < len && subject.charAt(start) == ' ') {
+ start++;
+ }
+
+ if (start < (len - 2)
+ && (subject.charAt(start) == 'r' || subject.charAt(start) == 'R')
+ && (subject.charAt(start + 1) == 'e' || subject.charAt(start + 1) == 'E')) {
+
+ if (subject.charAt(start + 2) == ':') {
+ start += 3; // Skip "Re:"
+ isReply = true;
+ done = false;
+ } else if (
+ start < (len - 2)
+ &&
+ (subject.charAt(start + 2) == '[' || subject.charAt(start + 2) == '(')) {
+
+ int i = start + 3;
+
+ while (i < len && subject.charAt(i) >= '0' && subject.charAt(i) <= '9')
+ i++;
+
+ if (i < (len - 1)
+ && (subject.charAt(i) == ']' || subject.charAt(i) == ')')
+ && subject.charAt(i + 1) == ':') {
+ start = i + 2;
+ isReply = true;
+ done = false;
+ }
+ }
+ }
+
+ if (simplifiedSubject == "(no subject)")
+ simplifiedSubject = "";
+
+ int end = len;
+
+ while (end > start && subject.charAt(end - 1) < ' ')
+ end--;
+
+ if (start == 0 && end == len)
+ simplifiedSubject = subject;
+ else
+ simplifiedSubject = subject.substring(start, end);
+ }
+ }
+
+ /**
+ * Recursive method that traverses a pre-threaded graph (or tree)
+ * of connected Article objects and prints them out.
+ * @param article the root of the article 'tree'
+ * @param depth the current tree depth
+ */
+ public static void printThread(Article article, int depth) {
+ for (int i = 0; i < depth; ++i)
+ System.out.print("==>");
+ System.out.println(article.getSubject() + "\t" + article.getFrom());
+ if (article.kid != null)
+ printThread(article.kid, depth + 1);
+ if (article.next != null)
+ printThread(article.next, depth);
+ }
+
+ public String getArticleId() {
+ return articleId;
+ }
+
+ public int getArticleNumber() {
+ return articleNumber;
+ }
+
+ public String getDate() {
+ return date;
+ }
+
+ public String getFrom() {
+ return from;
+ }
+
+ public String getSubject() {
+ return subject;
+ }
+
+ public void setArticleId(String string) {
+ articleId = string;
+ }
+
+ public void setArticleNumber(int i) {
+ articleNumber = i;
+ }
+
+ public void setDate(String string) {
+ date = string;
+ }
+
+ public void setFrom(String string) {
+ from = string;
+ }
+
+ public void setSubject(String string) {
+ subject = string;
+ }
+
+
+ public boolean isDummy() {
+ return (getSubject() == null);
+ }
+
+ public String messageThreadId() {
+ return articleId;
+ }
+
+ public String[] messageThreadReferences() {
+ return getReferences();
+ }
+
+ public String simplifiedSubject() {
+ if(simplifiedSubject == null)
+ simplifySubject();
+ return simplifiedSubject;
+ }
+
+
+ public boolean subjectIsReply() {
+ if(simplifiedSubject == null)
+ simplifySubject();
+ return isReply;
+ }
+
+
+ public void setChild(Threadable child) {
+ this.kid = (Article) child;
+ flushSubjectCache();
+ }
+
+ private void flushSubjectCache() {
+ simplifiedSubject = null;
+ }
+
+
+ public void setNext(Threadable next) {
+ this.next = (Article)next;
+ flushSubjectCache();
+ }
+
+
+ public Threadable makeDummy() {
+ return new Article();
+ }
}
Modified: commons/proper/net/trunk/src/java/org/apache/commons/net/nntp/NNTPClient.java
URL: http://svn.apache.org/viewvc/commons/proper/net/trunk/src/java/org/apache/commons/net/nntp/NNTPClient.java?rev=658491&r1=658490&r2=658491&view=diff
==============================================================================
--- commons/proper/net/trunk/src/java/org/apache/commons/net/nntp/NNTPClient.java (original)
+++ commons/proper/net/trunk/src/java/org/apache/commons/net/nntp/NNTPClient.java Tue May 20 16:48:50 2008
@@ -195,10 +195,10 @@
result._setFirstArticle(firstNum);
result._setLastArticle(lastNum);
- if((firstNum == 0) && (lastNum == 0))
- result._setArticleCount(0);
- else
- result._setArticleCount(lastNum - firstNum + 1);
+ if((firstNum == 0) && (lastNum == 0))
+ result._setArticleCount(0);
+ else
+ result._setArticleCount(lastNum - firstNum + 1);
}
catch (NumberFormatException e)
{
Modified: commons/proper/net/trunk/src/java/org/apache/commons/net/nntp/Threadable.java
URL: http://svn.apache.org/viewvc/commons/proper/net/trunk/src/java/org/apache/commons/net/nntp/Threadable.java?rev=658491&r1=658490&r2=658491&view=diff
==============================================================================
--- commons/proper/net/trunk/src/java/org/apache/commons/net/nntp/Threadable.java (original)
+++ commons/proper/net/trunk/src/java/org/apache/commons/net/nntp/Threadable.java Tue May 20 16:48:50 2008
@@ -22,12 +22,12 @@
*
*/
public interface Threadable {
- public boolean isDummy();
- public String messageThreadId();
- public String[] messageThreadReferences();
- public String simplifiedSubject();
- public boolean subjectIsReply();
- public void setChild(Threadable child);
- public void setNext(Threadable next);
- public Threadable makeDummy();
+ public boolean isDummy();
+ public String messageThreadId();
+ public String[] messageThreadReferences();
+ public String simplifiedSubject();
+ public boolean subjectIsReply();
+ public void setChild(Threadable child);
+ public void setNext(Threadable next);
+ public Threadable makeDummy();
}
\ No newline at end of file
Modified: commons/proper/net/trunk/src/java/org/apache/commons/net/nntp/Threader.java
URL: http://svn.apache.org/viewvc/commons/proper/net/trunk/src/java/org/apache/commons/net/nntp/Threader.java?rev=658491&r1=658490&r2=658491&view=diff
==============================================================================
--- commons/proper/net/trunk/src/java/org/apache/commons/net/nntp/Threader.java (original)
+++ commons/proper/net/trunk/src/java/org/apache/commons/net/nntp/Threader.java Tue May 20 16:48:50 2008
@@ -30,374 +30,374 @@
import java.util.Iterator;
public class Threader {
- private ThreadContainer root;
- private HashMap idTable;
- private int bogusIdCount = 0;
-
- /**
- * The main threader entry point - The client passes in an array of Threadable objects, and
- * the Threader constructs a connected 'graph' of messages
- * @param messages
- * @return
- */
- public Threadable thread(Threadable[] messages) {
- if (messages == null)
- return null;
-
- idTable = new HashMap();
-
- // walk through each Threadable element
- for (int i = 0; i < messages.length; ++i) {
- if (!messages[i].isDummy())
- buildContainer(messages[i]);
- }
-
- root = findRootSet();
- idTable.clear();
- idTable = null;
-
- pruneEmptyContainers(root);
-
- root.reverseChildren();
- gatherSubjects();
-
- if (root.next != null)
- throw new RuntimeException("root node has a next:" + root);
-
- for (ThreadContainer r = root.child; r != null; r = r.next) {
- if (r.threadable == null)
- r.threadable = r.child.threadable.makeDummy();
- }
-
- Threadable result = (root.child == null ? null : root.child.threadable);
- root.flush();
- root = null;
-
- return result;
- }
-
- /**
- *
- * @param threadable
- */
- private void buildContainer(Threadable threadable) {
- String id = threadable.messageThreadId();
- ThreadContainer container = (ThreadContainer) idTable.get(id);
-
- // A ThreadContainer exists for this id already. This should be a forward reference, but may
- // be a duplicate id, in which case we will need to generate a bogus placeholder id
- if (container != null) {
- if (container.threadable != null) { // oops! duplicate ids...
- id = "<Bogus-id:" + (bogusIdCount++) + ">";
- container = null;
- } else {
- // The container just contained a forward reference to this message, so let's
- // fill in the threadable field of the container with this message
- container.threadable = threadable;
- }
- }
-
- // No container exists for that message Id. Create one and insert it into the hash table.
- if (container == null) {
- container = new ThreadContainer();
- container.threadable = threadable;
- idTable.put(id, container);
- }
-
- // Iterate through all of the references and create ThreadContainers for any references that
- // don't have them.
- ThreadContainer parentRef = null;
- {
- String[] references = threadable.messageThreadReferences();
- for (int i = 0; i < references.length; ++i) {
- String refString = references[i];
- ThreadContainer ref = (ThreadContainer) idTable.get(refString);
-
- // if this id doesnt have a container, create one
- if (ref == null) {
- ref = new ThreadContainer();
- idTable.put(refString, ref);
- }
-
- // Link references together in the order they appear in the References: header,
- // IF they dont have a have a parent already &&
- // IF it will not cause a circular reference
- if ((parentRef != null)
- && (ref.parent == null)
- && (parentRef != ref)
- && !(parentRef.findChild(ref))) {
- // Link ref into the parent's child list
- ref.parent = parentRef;
- ref.next = parentRef.child;
- parentRef.child = ref;
- }
- parentRef = ref;
- }
- }
-
- // parentRef is now set to the container of the last element in the references field. make that
- // be the parent of this container, unless doing so causes a circular reference
- if (parentRef != null
- && (parentRef == container || container.findChild(parentRef)))
- parentRef = null;
-
- // if it has a parent already, its because we saw this message in a References: field, and presumed
- // a parent based on the other entries in that field. Now that we have the actual message, we can
- // throw away the old parent and use this new one
- if (container.parent != null) {
- ThreadContainer rest, prev;
-
- for (prev = null, rest = container.parent.child;
- rest != null;
- prev = rest, rest = rest.next) {
- if (rest == container)
- break;
- }
-
- if (rest == null) {
- throw new RuntimeException(
- "Didnt find "
- + container
- + " in parent"
- + container.parent);
- }
-
- // Unlink this container from the parent's child list
- if (prev == null)
- container.parent.child = container.next;
- else
- prev.next = container.next;
-
- container.next = null;
- container.parent = null;
- }
-
- // If we have a parent, link container into the parents child list
- if (parentRef != null) {
- container.parent = parentRef;
- container.next = parentRef.child;
- parentRef.child = container;
- }
- }
-
- /**
- * Find the root set of all existing ThreadContainers
- * @return root the ThreadContainer representing the root node
- */
- private ThreadContainer findRootSet() {
- ThreadContainer root = new ThreadContainer();
- Iterator iter = idTable.keySet().iterator();
-
- while (iter.hasNext()) {
- Object key = iter.next();
- ThreadContainer c = (ThreadContainer) idTable.get(key);
- if (c.parent == null) {
- if (c.next != null)
- throw new RuntimeException(
- "c.next is " + c.next.toString());
- c.next = root.child;
- root.child = c;
- }
- }
- return root;
- }
-
- /**
- * Delete any empty or dummy ThreadContainers
- * @param parent
- */
- private void pruneEmptyContainers(ThreadContainer parent) {
- ThreadContainer container, prev, next;
- for (prev = null, container = parent.child, next = container.next;
- container != null;
- prev = container,
- container = next,
- next = (container == null ? null : container.next)) {
-
- // Is it empty and without any children? If so,delete it
- if (container.threadable == null && container.child == null) {
- if (prev == null)
- parent.child = container.next;
- else
- prev.next = container.next;
-
- // Set container to prev so that prev keeps its same value the next time through the loop
- container = prev;
- }
-
- // Else if empty, with kids, and (not at root or only one kid)
- else if (
- container.threadable == null
- && container.child != null
- && (container.parent != null
- || container.child.next == null)) {
- // We have an invalid/expired message with kids. Promote the kids to this level.
- ThreadContainer tail;
- ThreadContainer kids = container.child;
-
- // Remove this container and replace with 'kids'.
- if (prev == null)
- parent.child = kids;
- else
- prev.next = kids;
-
- // Make each child's parent be this level's parent -> i.e. promote the children. Make the last child's next point to this container's next
- // i.e. splice kids into the list in place of container
- for (tail = kids; tail.next != null; tail = tail.next)
- tail.parent = container.parent;
-
- tail.parent = container.parent;
- tail.next = container.next;
-
- // next currently points to the item after the inserted items in the chain - reset that so we process the newly
- // promoted items next time round
- next = kids;
-
- // Set container to prev so that prev keeps its same value the next time through the loop
- container = prev;
- } else if (container.child != null) {
- // A real message , with kids
- // Iterate over the children
- pruneEmptyContainers(container);
- }
- }
- }
-
- /**
- * If any two members of the root set have the same subject, merge them. This is to attempt to accomodate messages without References: headers.
- */
- private void gatherSubjects() {
-
- int count = 0;
-
- for (ThreadContainer c = root.child; c != null; c = c.next)
- count++;
-
- // TODO verify this will avoid rehashing
- HashMap subjectTable = new HashMap((int) (count * 1.2), (float) 0.9);
- count = 0;
-
- for (ThreadContainer c = root.child; c != null; c = c.next) {
- Threadable threadable = c.threadable;
-
- // No threadable? If so, it is a dummy node in the root set.
- // Only root set members may be dummies, and they alway have at least 2 kids
- // Take the first kid as representative of the subject
- if (threadable == null)
- threadable = c.child.threadable;
-
- String subj = threadable.simplifiedSubject();
-
- if (subj == null || subj == "")
- continue;
-
- ThreadContainer old = (ThreadContainer) subjectTable.get(subj);
-
- // Add this container to the table iff:
- // - There exists no container with this subject
- // - or this is a dummy container and the old one is not - the dummy one is
- // more interesting as a root, so put it in the table instead
- // - The container in the table has a "Re:" version of this subject, and
- // this container has a non-"Re:" version of this subject. The non-"Re:" version
- // is the more interesting of the two.
- if (old == null
- || (c.threadable == null && old.threadable != null)
- || (old.threadable != null
- && old.threadable.subjectIsReply()
- && c.threadable != null
- && !c.threadable.subjectIsReply())) {
- subjectTable.put(subj, c);
- count++;
- }
- }
-
- // If the table is empty, we're done
- if (count == 0)
- return;
-
- // subjectTable is now populated with one entry for each subject which occurs in the
- // root set. Iterate over the root set, and gather together the difference.
- ThreadContainer prev, c, rest;
- for (prev = null, c = root.child, rest = c.next;
- c != null;
- prev = c, c = rest, rest = (rest == null ? null : rest.next)) {
- Threadable threadable = c.threadable;
-
- // is it a dummy node?
- if (threadable == null)
- threadable = c.child.threadable;
-
- String subj = threadable.simplifiedSubject();
-
- // Dont thread together all subjectless messages
- if (subj == null || subj == "")
- continue;
-
- ThreadContainer old = (ThreadContainer) subjectTable.get(subj);
-
- if (old == c) // That's us
- continue;
-
- // We have now found another container in the root set with the same subject
- // Remove the "second" message from the root set
- if (prev == null)
- root.child = c.next;
- else
- prev.next = c.next;
- c.next = null;
-
- if (old.threadable == null && c.threadable == null) {
- // both dummies - merge them
- ThreadContainer tail;
- for (tail = old.child;
- tail != null && tail.next != null;
- tail = tail.next);
-
- tail.next = c.child;
-
- for (tail = c.child; tail != null; tail = tail.next)
- tail.parent = old;
-
- c.child = null;
- } else if (
- old.threadable == null
- || (c.threadable != null
- && c.threadable.subjectIsReply()
- && !old.threadable.subjectIsReply())) {
- // Else if old is empty, or c has "Re:" and old does not ==> make this message a child of old
- c.parent = old;
- c.next = old.child;
- old.child = c;
- } else {
- // else make the old and new messages be children of a new dummy container.
- // We create a new container object for old.msg and empty the old container
- ThreadContainer newc = new ThreadContainer();
- newc.threadable = old.threadable;
- newc.child = old.child;
-
- for (ThreadContainer tail = newc.child;
- tail != null;
- tail = tail.next)
- tail.parent = newc;
-
- old.threadable = null;
- old.child = null;
-
- c.parent = old;
- newc.parent = old;
-
- // Old is now a dummy- give it 2 kids , c and newc
- old.child = c;
- c.next = newc;
- }
- // We've done a merge, so keep the same prev
- c = prev;
- }
+ private ThreadContainer root;
+ private HashMap idTable;
+ private int bogusIdCount = 0;
+
+ /**
+ * The main threader entry point - The client passes in an array of Threadable objects, and
+ * the Threader constructs a connected 'graph' of messages
+ * @param messages
+ * @return
+ */
+ public Threadable thread(Threadable[] messages) {
+ if (messages == null)
+ return null;
+
+ idTable = new HashMap();
+
+ // walk through each Threadable element
+ for (int i = 0; i < messages.length; ++i) {
+ if (!messages[i].isDummy())
+ buildContainer(messages[i]);
+ }
+
+ root = findRootSet();
+ idTable.clear();
+ idTable = null;
+
+ pruneEmptyContainers(root);
+
+ root.reverseChildren();
+ gatherSubjects();
+
+ if (root.next != null)
+ throw new RuntimeException("root node has a next:" + root);
+
+ for (ThreadContainer r = root.child; r != null; r = r.next) {
+ if (r.threadable == null)
+ r.threadable = r.child.threadable.makeDummy();
+ }
+
+ Threadable result = (root.child == null ? null : root.child.threadable);
+ root.flush();
+ root = null;
+
+ return result;
+ }
+
+ /**
+ *
+ * @param threadable
+ */
+ private void buildContainer(Threadable threadable) {
+ String id = threadable.messageThreadId();
+ ThreadContainer container = (ThreadContainer) idTable.get(id);
+
+ // A ThreadContainer exists for this id already. This should be a forward reference, but may
+ // be a duplicate id, in which case we will need to generate a bogus placeholder id
+ if (container != null) {
+ if (container.threadable != null) { // oops! duplicate ids...
+ id = "<Bogus-id:" + (bogusIdCount++) + ">";
+ container = null;
+ } else {
+ // The container just contained a forward reference to this message, so let's
+ // fill in the threadable field of the container with this message
+ container.threadable = threadable;
+ }
+ }
+
+ // No container exists for that message Id. Create one and insert it into the hash table.
+ if (container == null) {
+ container = new ThreadContainer();
+ container.threadable = threadable;
+ idTable.put(id, container);
+ }
+
+ // Iterate through all of the references and create ThreadContainers for any references that
+ // don't have them.
+ ThreadContainer parentRef = null;
+ {
+ String[] references = threadable.messageThreadReferences();
+ for (int i = 0; i < references.length; ++i) {
+ String refString = references[i];
+ ThreadContainer ref = (ThreadContainer) idTable.get(refString);
+
+ // if this id doesnt have a container, create one
+ if (ref == null) {
+ ref = new ThreadContainer();
+ idTable.put(refString, ref);
+ }
+
+ // Link references together in the order they appear in the References: header,
+ // IF they dont have a have a parent already &&
+ // IF it will not cause a circular reference
+ if ((parentRef != null)
+ && (ref.parent == null)
+ && (parentRef != ref)
+ && !(parentRef.findChild(ref))) {
+ // Link ref into the parent's child list
+ ref.parent = parentRef;
+ ref.next = parentRef.child;
+ parentRef.child = ref;
+ }
+ parentRef = ref;
+ }
+ }
+
+ // parentRef is now set to the container of the last element in the references field. make that
+ // be the parent of this container, unless doing so causes a circular reference
+ if (parentRef != null
+ && (parentRef == container || container.findChild(parentRef)))
+ parentRef = null;
+
+ // if it has a parent already, its because we saw this message in a References: field, and presumed
+ // a parent based on the other entries in that field. Now that we have the actual message, we can
+ // throw away the old parent and use this new one
+ if (container.parent != null) {
+ ThreadContainer rest, prev;
+
+ for (prev = null, rest = container.parent.child;
+ rest != null;
+ prev = rest, rest = rest.next) {
+ if (rest == container)
+ break;
+ }
+
+ if (rest == null) {
+ throw new RuntimeException(
+ "Didnt find "
+ + container
+ + " in parent"
+ + container.parent);
+ }
+
+ // Unlink this container from the parent's child list
+ if (prev == null)
+ container.parent.child = container.next;
+ else
+ prev.next = container.next;
+
+ container.next = null;
+ container.parent = null;
+ }
+
+ // If we have a parent, link container into the parents child list
+ if (parentRef != null) {
+ container.parent = parentRef;
+ container.next = parentRef.child;
+ parentRef.child = container;
+ }
+ }
+
+ /**
+ * Find the root set of all existing ThreadContainers
+ * @return root the ThreadContainer representing the root node
+ */
+ private ThreadContainer findRootSet() {
+ ThreadContainer root = new ThreadContainer();
+ Iterator iter = idTable.keySet().iterator();
+
+ while (iter.hasNext()) {
+ Object key = iter.next();
+ ThreadContainer c = (ThreadContainer) idTable.get(key);
+ if (c.parent == null) {
+ if (c.next != null)
+ throw new RuntimeException(
+ "c.next is " + c.next.toString());
+ c.next = root.child;
+ root.child = c;
+ }
+ }
+ return root;
+ }
+
+ /**
+ * Delete any empty or dummy ThreadContainers
+ * @param parent
+ */
+ private void pruneEmptyContainers(ThreadContainer parent) {
+ ThreadContainer container, prev, next;
+ for (prev = null, container = parent.child, next = container.next;
+ container != null;
+ prev = container,
+ container = next,
+ next = (container == null ? null : container.next)) {
+
+ // Is it empty and without any children? If so,delete it
+ if (container.threadable == null && container.child == null) {
+ if (prev == null)
+ parent.child = container.next;
+ else
+ prev.next = container.next;
+
+ // Set container to prev so that prev keeps its same value the next time through the loop
+ container = prev;
+ }
+
+ // Else if empty, with kids, and (not at root or only one kid)
+ else if (
+ container.threadable == null
+ && container.child != null
+ && (container.parent != null
+ || container.child.next == null)) {
+ // We have an invalid/expired message with kids. Promote the kids to this level.
+ ThreadContainer tail;
+ ThreadContainer kids = container.child;
+
+ // Remove this container and replace with 'kids'.
+ if (prev == null)
+ parent.child = kids;
+ else
+ prev.next = kids;
+
+ // Make each child's parent be this level's parent -> i.e. promote the children. Make the last child's next point to this container's next
+ // i.e. splice kids into the list in place of container
+ for (tail = kids; tail.next != null; tail = tail.next)
+ tail.parent = container.parent;
+
+ tail.parent = container.parent;
+ tail.next = container.next;
+
+ // next currently points to the item after the inserted items in the chain - reset that so we process the newly
+ // promoted items next time round
+ next = kids;
+
+ // Set container to prev so that prev keeps its same value the next time through the loop
+ container = prev;
+ } else if (container.child != null) {
+ // A real message , with kids
+ // Iterate over the children
+ pruneEmptyContainers(container);
+ }
+ }
+ }
+
+ /**
+ * If any two members of the root set have the same subject, merge them. This is to attempt to accomodate messages without References: headers.
+ */
+ private void gatherSubjects() {
+
+ int count = 0;
+
+ for (ThreadContainer c = root.child; c != null; c = c.next)
+ count++;
+
+ // TODO verify this will avoid rehashing
+ HashMap subjectTable = new HashMap((int) (count * 1.2), (float) 0.9);
+ count = 0;
+
+ for (ThreadContainer c = root.child; c != null; c = c.next) {
+ Threadable threadable = c.threadable;
+
+ // No threadable? If so, it is a dummy node in the root set.
+ // Only root set members may be dummies, and they alway have at least 2 kids
+ // Take the first kid as representative of the subject
+ if (threadable == null)
+ threadable = c.child.threadable;
+
+ String subj = threadable.simplifiedSubject();
+
+ if (subj == null || subj == "")
+ continue;
+
+ ThreadContainer old = (ThreadContainer) subjectTable.get(subj);
+
+ // Add this container to the table iff:
+ // - There exists no container with this subject
+ // - or this is a dummy container and the old one is not - the dummy one is
+ // more interesting as a root, so put it in the table instead
+ // - The container in the table has a "Re:" version of this subject, and
+ // this container has a non-"Re:" version of this subject. The non-"Re:" version
+ // is the more interesting of the two.
+ if (old == null
+ || (c.threadable == null && old.threadable != null)
+ || (old.threadable != null
+ && old.threadable.subjectIsReply()
+ && c.threadable != null
+ && !c.threadable.subjectIsReply())) {
+ subjectTable.put(subj, c);
+ count++;
+ }
+ }
+
+ // If the table is empty, we're done
+ if (count == 0)
+ return;
+
+ // subjectTable is now populated with one entry for each subject which occurs in the
+ // root set. Iterate over the root set, and gather together the difference.
+ ThreadContainer prev, c, rest;
+ for (prev = null, c = root.child, rest = c.next;
+ c != null;
+ prev = c, c = rest, rest = (rest == null ? null : rest.next)) {
+ Threadable threadable = c.threadable;
+
+ // is it a dummy node?
+ if (threadable == null)
+ threadable = c.child.threadable;
+
+ String subj = threadable.simplifiedSubject();
+
+ // Dont thread together all subjectless messages
+ if (subj == null || subj == "")
+ continue;
+
+ ThreadContainer old = (ThreadContainer) subjectTable.get(subj);
+
+ if (old == c) // That's us
+ continue;
+
+ // We have now found another container in the root set with the same subject
+ // Remove the "second" message from the root set
+ if (prev == null)
+ root.child = c.next;
+ else
+ prev.next = c.next;
+ c.next = null;
+
+ if (old.threadable == null && c.threadable == null) {
+ // both dummies - merge them
+ ThreadContainer tail;
+ for (tail = old.child;
+ tail != null && tail.next != null;
+ tail = tail.next);
+
+ tail.next = c.child;
+
+ for (tail = c.child; tail != null; tail = tail.next)
+ tail.parent = old;
+
+ c.child = null;
+ } else if (
+ old.threadable == null
+ || (c.threadable != null
+ && c.threadable.subjectIsReply()
+ && !old.threadable.subjectIsReply())) {
+ // Else if old is empty, or c has "Re:" and old does not ==> make this message a child of old
+ c.parent = old;
+ c.next = old.child;
+ old.child = c;
+ } else {
+ // else make the old and new messages be children of a new dummy container.
+ // We create a new container object for old.msg and empty the old container
+ ThreadContainer newc = new ThreadContainer();
+ newc.threadable = old.threadable;
+ newc.child = old.child;
+
+ for (ThreadContainer tail = newc.child;
+ tail != null;
+ tail = tail.next)
+ tail.parent = newc;
+
+ old.threadable = null;
+ old.child = null;
+
+ c.parent = old;
+ newc.parent = old;
+
+ // Old is now a dummy- give it 2 kids , c and newc
+ old.child = c;
+ c.next = newc;
+ }
+ // We've done a merge, so keep the same prev
+ c = prev;
+ }
- subjectTable.clear();
- subjectTable = null;
+ subjectTable.clear();
+ subjectTable = null;
- }
+ }
}
/**
@@ -408,73 +408,73 @@
* @author Rory Winston <rw...@checkfree.com>
*/
class ThreadContainer {
- Threadable threadable;
- ThreadContainer parent;
- ThreadContainer prev;
- ThreadContainer next;
- ThreadContainer child;
-
- /**
- *
- * @param container
- * @return true if child is under self's tree. Detects circular references
- */
- boolean findChild(ThreadContainer target) {
- if (child == null)
- return false;
-
- else if (child == target)
- return true;
- else
- return child.findChild(target);
- }
-
- // Copy the ThreadContainer tree structure down into the underlying Threadable objects
- // (Make the Threadable tree look like the ThreadContainer tree)
- void flush() {
- if (parent != null && threadable == null)
- throw new RuntimeException("no threadable in " + this.toString());
-
- parent = null;
-
- if (threadable != null)
- threadable.setChild(child == null ? null : child.threadable);
-
- if (child != null) {
- child.flush();
- child = null;
- }
-
- if (threadable != null)
- threadable.setNext(next == null ? null : next.threadable);
-
- if (next != null) {
- next.flush();
- next = null;
- }
-
- threadable = null;
- }
-
- /**
- * Reverse the entire set of children
- *
- */
- void reverseChildren() {
- if (child != null) {
- ThreadContainer kid, prev, rest;
- for (prev = null, kid = child, rest = kid.next;
- kid != null;
- prev = kid,
- kid = rest,
- rest = (rest == null ? null : rest.next))
- kid.next = prev;
-
- child = prev;
-
- // Do it for the kids
- for (kid = child; kid != null; kid = kid.next)
- kid.reverseChildren();
- }
- }
+ Threadable threadable;
+ ThreadContainer parent;
+ ThreadContainer prev;
+ ThreadContainer next;
+ ThreadContainer child;
+
+ /**
+ *
+ * @param container
+ * @return true if child is under self's tree. Detects circular references
+ */
+ boolean findChild(ThreadContainer target) {
+ if (child == null)
+ return false;
+
+ else if (child == target)
+ return true;
+ else
+ return child.findChild(target);
+ }
+
+ // Copy the ThreadContainer tree structure down into the underlying Threadable objects
+ // (Make the Threadable tree look like the ThreadContainer tree)
+ void flush() {
+ if (parent != null && threadable == null)
+ throw new RuntimeException("no threadable in " + this.toString());
+
+ parent = null;
+
+ if (threadable != null)
+ threadable.setChild(child == null ? null : child.threadable);
+
+ if (child != null) {
+ child.flush();
+ child = null;
+ }
+
+ if (threadable != null)
+ threadable.setNext(next == null ? null : next.threadable);
+
+ if (next != null) {
+ next.flush();
+ next = null;
+ }
+
+ threadable = null;
+ }
+
+ /**
+ * Reverse the entire set of children
+ *
+ */
+ void reverseChildren() {
+ if (child != null) {
+ ThreadContainer kid, prev, rest;
+ for (prev = null, kid = child, rest = kid.next;
+ kid != null;
+ prev = kid,
+ kid = rest,
+ rest = (rest == null ? null : rest.next))
+ kid.next = prev;
+
+ child = prev;
+
+ // Do it for the kids
+ for (kid = child; kid != null; kid = kid.next)
+ kid.reverseChildren();
+ }
+ }
}
Modified: commons/proper/net/trunk/src/java/org/apache/commons/net/ntp/NtpV3Impl.java
URL: http://svn.apache.org/viewvc/commons/proper/net/trunk/src/java/org/apache/commons/net/ntp/NtpV3Impl.java?rev=658491&r1=658490&r2=658491&view=diff
==============================================================================
--- commons/proper/net/trunk/src/java/org/apache/commons/net/ntp/NtpV3Impl.java (original)
+++ commons/proper/net/trunk/src/java/org/apache/commons/net/ntp/NtpV3Impl.java Tue May 20 16:48:50 2008
@@ -95,10 +95,10 @@
/***
* Returns leap indicator as defined in RFC-1305 which is a two-bit code:
- * 0=no warning
- * 1=last minute has 61 seconds
- * 2=last minute has 59 seconds
- * 3=alarm condition (clock not synchronized)
+ * 0=no warning
+ * 1=last minute has 61 seconds
+ * 2=last minute has 59 seconds
+ * 3=alarm condition (clock not synchronized)
*
* @return leap indicator as defined in RFC-1305.
*/
Modified: commons/proper/net/trunk/src/java/org/apache/commons/net/ntp/TimeInfo.java
URL: http://svn.apache.org/viewvc/commons/proper/net/trunk/src/java/org/apache/commons/net/ntp/TimeInfo.java?rev=658491&r1=658490&r2=658491&view=diff
==============================================================================
--- commons/proper/net/trunk/src/java/org/apache/commons/net/ntp/TimeInfo.java (original)
+++ commons/proper/net/trunk/src/java/org/apache/commons/net/ntp/TimeInfo.java Tue May 20 16:48:50 2008
@@ -153,7 +153,7 @@
* according to this standard NTP equation:
*
* LocalClockOffset = ((ReceiveTimestamp - OriginateTimestamp) +
- * (TransmitTimestamp - DestinationTimestamp)) / 2
+ * (TransmitTimestamp - DestinationTimestamp)) / 2
*
* equations from RFC-1305 (NTPv3)
* roundtrip delay = (t4 - t1) - (t3 - t2)