Volunteer Work

2023-05-26 Thread Miguel Munoz
Gary,
The last time we communicated about this, you were expecting to need help with 
BeanUtils 2. Do you still need help with that? If not, what else can I help 
with?
— Miguel Muñoz
———
4210 Via Arbolada #226Los Angeles, CA 90042
323-225-7285
–

The Sun, with all those planets going around it and dependent on it, can still 
ripen a vine of grapes like it has nothing else to do in the world.
  — Galileo

[IO] Commons IOIO-552 FilenameUtils.concat fails if second argument (fullFilenameToAdd) starts with '~' (tilde)

2023-05-26 Thread Miguel Munoz
Gary D. Gregory,
I've offered two suggestions of how to fix Commons IOIO-552.
One is add a new method called configStrict(), which treats tildes as part of 
the file name.The other is to deprecate the class and write a whole new class 
(FilenameUtils2 ?) that treats the tilde character as just another character, 
instead of using linux shell conventions.

If you're happy with either of these approaches, I'd be happy to take this 
on.If you have other priorities you'd like help with, please let me know.
— Miguel Muñoz

Re: [compress] Dealing with uncaught RuntimeExceptions (again)

2021-06-29 Thread Miguel Munoz
Catching all RuntimeExceptions and wrapping them in an IOException looks like 
the cleanest solution. RuntimeExceptions usually mean bugs, so if the archive 
code is throwing them due to a corrupted archive, it makes sense to wrap it in 
a checked exception. I would like to suggest creating a new class looking 
something like this: 

public class CorruptedArchiveException extends IOException { }
In fact, since we will only be generating them in response to a 
RuntimeException, we may want to make sure all constructors require an 
RuntimeException as a parameter, to guarantee that we wrap the original 
unchecked exception.
— Miguel Muñoz
———
4210 Via Arbolada #226Los Angeles, CA 90042
323-225-7285
–

The Sun, with all those planets going around it and dependent on it, can still 
ripen a vine of grapes like it has nothing else to do in the world.
  — Galileo 

On Monday, June 28, 2021, 06:52:02 AM PDT, Gilles Sadowski 
 wrote:  
 
 Le lun. 28 juin 2021 à 08:52, Stefan Bodewig  a écrit :
>
> On 2021-06-27, Gilles Sadowski wrote:
>
> > Le dim. 27 juin 2021 à 21:15, Stefan Bodewig  a écrit :
>
> >> As I said, we can as well document that each method could throw
> >> arbitrary RuntimeExceptions, but I don't believe we can list the kinds
> >> of RuntimeExceptions exhaustively
>
> > Why not?
> > Listing all runtime exceptions is considered part of good
> > documentation.
>
> Because we do not know which RuntimeExceptions may be caused by an
> invalid archive.
>
> Most of the RuntimeException happen because our parsers believe in a
> world where every archive is valid. For example we may read a few bytes
> that are the size of an array and then create the array without checking
> whether the size is negative and a NegativeArraySizeException occurs.
>
> As we haven't considered the case of a negative size in code, we also do
> not know this exception could be thrown. If we had considered the case
> of negative sizes, the parser could have avoided the exception
> alltogether. This is what I meant with
>
> >> - if we knew which exceptions can be thrown, then we could as well
> >> check the error conditions ourselves beforehand.
>
> Our parsers could of course be hardened, but this is pretty difficult to
> do years after they've been written and would certainly miss a few
> corner cases anyway.

Thank you for the example.  I now understand that the aim is not
to increase the number of precondition checks but only to ensure
that a single exception can escape from calls with "undefined"
behaviour whenever some precondition is not fulfilled.

IIUC, the situation where the library assumes some precondition
but does not check it, and continues its operations until something
unexpected occurs, would be described by "IllegalStateException".
[A very much "non-recoverable" state, as the library doesn't know
the root cause (which may be a long way from where the symptom
appeared).]

In principle, it looks interesting information for users to be able to
distinguish between a known failure (i.e. the library knows the root
cause) and an unknown failure (?).

> And then there is a certain category of exceptions thrown by Java
> classlib methods we invoke. We've just added a catch block around
> java.util.zip.ZipEntry#setExtra because certain invalid archives cause a
> RuntimeException there - and if I remember correctly a RuntimeException
> the method's javadoc doesn't list.

It shows that similar JDK functionality can indeed throw a runtime
exception when it gets unexpected garbage.  What is their rationale
for choosing this or "IOException" (I have no idea)?

Regards,
Gilles

-
To unsubscribe, e-mail: dev-unsubscr...@commons.apache.org
For additional commands, e-mail: dev-h...@commons.apache.org

  

Re: Roman number conversion to Integer

2021-05-27 Thread Miguel Munoz
Here's one take on the problem:
 /**
 * Created by IntelliJ IDEA.
 * Date: 2/4/21
 * Time: 1:36 AM
 *
 * @author Miguel Mu\u00f1oz
 */
public class ToRomans {
  private static int[] divisors = {1000, 500, 100, 50, 10, 5, 1};
  private static char[] romans = {'M', 'D', 'C', 'L', 'X', 'V', 'I'};

  /**
   * Convert a positive, non-zero integer to Roman numerals.
   * Roman numerals are usually written largest to smallest from left to right. 
However, the numeral for four is not . Instead,
   * the number four is written as IV. Because the one is before the five we 
subtract it making four. The same principle applies to
   * the number nine, which is written as IX. There are six instances where 
subtraction is used:
   *
   * I can be placed before V (5) and X (10) to make 4 and 9. 
   * X can be placed before L (50) and C (100) to make 40 and 90. 
   * C can be placed before D (500) and M (1000) to make 400 and 900.
   *
   * Zero cannot be expressed in Roman numerals. The Romans never invented 
zero. (Yeah. I'm serious.)
   * @param num The number to convert
   * @return A string expressing the number in Roman numerals
   */
  public String intToRoman(final int num) {
if ((num < 1) || (num > 3999)) {
  throw new IllegalArgumentException(String.format("Value %d is out of 
range (1 - 3999)", num));
}
int val = num;
StringBuilder builder = new StringBuilder();
for (int i = 0; i < divisors.length; i += 2) {
  int mod = divisors[i];
  int v = val / mod;
  if (v > 0) {
if (v == 9) {
  builder.append(romans[i]);
  builder.append(romans[i - 2]);
} else if (v >= 5) {
  builder.append(romans[i - 1]);
  builder.append(repeat(romans[i], v-5));
} else if (v == 4) {
  builder.append(romans[i]);
  builder.append(romans[i - 1]);
} else {
  builder.append(repeat(romans[i], v));
}
val -= v * divisors[i];
  }
}
return builder.toString();
  }
  
  private static char[] repeat(char c, int count) {
char[] data = new char[count];
Arrays.fill(data, c);
return data;
  }

  public static void main(String[] args) {
int[] testCases = {1, 4, 5, 6, 8, 9, 10, 11, 13, 14, 15, 30, 32, 36, 39, 
125, 234, 345, 456, 567, 678, 789, 890, 891, 900, 901, 912, 1234, 2345, 3456, 
1567, 2678, 3789, 2001, 2493, 2587, 3888, 3999};
ToRomans s = new ToRomans();
for (int test : testCases) {
  System.out.printf("%4d = %s%n", test, s.intToRoman(test));
}
test();
  }
  
  private static void test() {
Map dataMap = new HashMap<>();
load(dataMap, 1, "I");
load(dataMap, 4, "IV");
load(dataMap, 5, "V");
load(dataMap, 6, "VI");
load(dataMap, 8, "VIII");
load(dataMap, 9, "IX");
load(dataMap, 10, "X");
load(dataMap, 11, "XI");
load(dataMap, 13, "XIII");
load(dataMap, 14, "XIV");
load(dataMap, 15, "XV");
load(dataMap, 30, "XXX");
load(dataMap, 32, "XXXII");
load(dataMap, 36, "XXXVI");
load(dataMap, 39, "XXXIX");
load(dataMap, 125, "CXXV");
load(dataMap, 234, "CCXXXIV");
load(dataMap, 345, "CCCXLV");
load(dataMap, 456, "CDLVI");
load(dataMap, 567, "DLXVII");
load(dataMap, 678, "DCLXXVIII");
load(dataMap, 789, "DCCLXXXIX");
load(dataMap, 890, "DCCCXC");
load(dataMap, 891, "DCCCXCI");
load(dataMap, 900, "CM");
load(dataMap, 901, "CMI");
load(dataMap, 912, "CMXII");
load(dataMap, 1234, "MCCXXXIV");
load(dataMap, 2345, "MMCCCXLV");
load(dataMap, 3456, "MMMCDLVI");
load(dataMap, 1567, "MDLXVII");
load(dataMap, 2678, "MMDCLXXVIII");
load(dataMap, 3789, "MMMDCCLXXXIX");
load(dataMap, 2001, "MMI");
load(dataMap, 2493, "MMCDXCIII");
load(dataMap, 2587, "MMDLXXXVII");
load(dataMap, 3888, "MMMDCCCLXXXVIII");
load(dataMap, 3999, "MMMCMXCIX");
ToRomans toRomans = new ToRomans();
for (Integer i: dataMap.keySet()) {
  String expected = dataMap.get(i);
  String actual = toRomans.intToRoman(i);
//  assertEquals(String.valueOf(i), expected, actual);
  if (!expected.equals(actual)) { // in JUnit, replace this block with the 
line commented out above.
throw new AssertionError(String.format("For %d, expected %s, got %s", 
i, expected, actual));
  }
}
  }
  
  private static void load(Map map, int i, String result) {
map.put(i, result);
  }
}

— Miguel Muñoz
———
4210 Via Arbolada #226Los Angeles, CA 90042
323-225-7285
–

The Sun, with all those planets going around it and dependent on it, can still 
ripen a vine of grapes like it has nothing else to do in the world.
  — Galileo 

On Thursday, May 27, 2021, 03:21:09 PM PDT, Thad Guidry 
 wrote:  
 
 Hello,

I've checked the source of https://commons.apache.org/proper/commons-numbers
but didn't find support for Roman numeral conversion.

Is this in another project?
Not at all?
Planned for Numbers or another subproject like Lang, Text, or Math?

Thad
h

Quick questions about this mailing list

2020-06-12 Thread Miguel Munoz
When I send an email to this list, my email address shows up in the archive as 
ending with .INVALID. Is there anything I can do about this? (I submitted an 
ICLA, so that shouldn't be the problem.)
-- Miguel Muñoz

-
To unsubscribe, e-mail: dev-unsubscr...@commons.apache.org
For additional commands, e-mail: dev-h...@commons.apache.org



[lang] Submitted patch for documentation fix LANG-1567

2020-06-12 Thread Miguel Munoz
I made a minor change to the documentation. I'm not sure if I should have left 
the issue open or marked it "Resolved." Right now, it's marked Resolved, 
although "Patch Available" would be more appropriate, but I can't figure out 
how to specify that resolution.
-- Miguel Munoz

-
To unsubscribe, e-mail: dev-unsubscr...@commons.apache.org
For additional commands, e-mail: dev-h...@commons.apache.org



LANG-1499 Equals transitivity is violated in EqualsBuilder

2020-06-10 Thread Miguel Munoz
I have a suggestion for how to fix this. First, I want to point out a problem 
with a proposed fix by a previous poster. The suggestion was:

One potential fix could be to have another else if branch to check if two 
classes share a common superclass.

As I mentioned on the bug page, this wouldn't have worked on a past project of 
mine. All our entity beans shared a common base class, which implemented 
equals() by using reflectionEquals(). This way, all our entities got an 
equals() method for free. Any two entities of different classes would be seen 
as not equal. But if we implement the proposed fix, then any two entities of 
different classes would now be equal. This doesn't seem like a good idea.

Here's another idea. Allow the user to specify which parent class to use for 
doing the comparison. So, for the revised test case, the call to 
reflectionEquals() might look more like this:  return 
EqualsBuilder.reflectionEquals(C.class, this, other);

The hazard here is that there are other overloaded methods that take a Class 
instance to specify the reflectUpTo property. We would need to design the API 
to reduce the likelihood that these two parameter could get confused.

-- Miguel Munoz

-
To unsubscribe, e-mail: dev-unsubscr...@commons.apache.org
For additional commands, e-mail: dev-h...@commons.apache.org



Re: [LANG] Porting to Kotlin

2020-04-25 Thread Miguel Munoz
 This sounds like a good idea to me, too. I'm not a contributor, by I'd be 
happy to join in and help.
-- Miguel Muñoz
On Friday, April 24, 2020, 11:17:44 PM PDT, Isira Seneviratne 
 wrote:  
 
 On Sat, Apr 25, 2020, 11:45 AM Isira Seneviratne 
wrote:

>
>
> On Sat, Apr 25, 2020, 11:22 AM Paul King 
> wrote:
>
>> The attachments didn't seem to come through. I am not on the commons PMC
>> but I would be -1 for changing the existing functionality.
>
>
That isn't my intention.

They already
>> work fine for Java and work already as Apache Groovy extension methods:
>>
>> @Grab('org.apache.commons:commons-lang3:3.10')
>> import org.apache.commons.lang3.StringUtils
>>
>> use(StringUtils) {
>>    assert 'The quick brown fox'.abbreviateMiddle('..', 8) == 'The..fox'
>>    assert 'abcdef'.rotate(3) == 'defabc'
>> }
>>
>> Rather than talking about "porting", why not just create a thin
>> re-purposing layer that provides additional functionality to Kotlin users.
>> That would be easy to do as a separate project and could be incorporated
>> into commons lang at a later date if there was sufficient interest?
>>
>
> Yeah, that sounds like a good idea. Thanks!
>
>
>> Cheers, Paul.
>>
>>
>> On Sat, Apr 25, 2020 at 2:24 PM Isira Seneviratne 
>> wrote:
>>
>> > 
>> > On Mon, Apr 20, 2020 at 8:41 PM Isira Seneviratne > >
>> > wrote:
>> >
>> >> Hi all,
>> >>
>> >> I'm a new contributor, but I've been using Commons Lang for a while
>> now,
>> >> and I feel that porting Commons Lang to Kotlin would be very useful for
>> >> Kotlin development, as a lot of its methods (particularly those in the
>> >> Utils classes) are not present in the Kotlin standard library, and
>> these
>> >> could be written as extensions
>> >> .
>> >>
>> >> What do you guys think?
>> >> --
>> >> Isira Seneviratne
>> >> isirase...@gmail.com
>> >>
>> >
>> > I have attached some sample files if anyone is interested.
>> > --
>> > Isira Seneviratne
>> > isirase...@gmail.com
>> >
>> > -
>> > To unsubscribe, e-mail: dev-unsubscr...@commons.apache.org
>> > For additional commands, e-mail: dev-h...@commons.apache.org
>>
>
  

Re: [numbers] NUMBERS-40: Exception Consistency

2020-02-03 Thread Miguel Munoz
Maybe some examples would be helpful.

-- Miguel Muñoz






On Sunday, February 2, 2020, 02:17:29 AM PST, Gilles Sadowski 
 wrote: 





Hi.

2020-01-26 16:54 UTC+01:00, Matt Juntunen :
> Hello,
>
> I'm looking into NUMBERS-40, which suggests that the exception behavior of
> commons-numbers (specifically the gamma package) needs to be made more
> consistent. Below is a summary of the public exception types explicitly
> thrown by each module.
>
> arrays
>        IndexOutOfBoundsException
>        IllegalArgumentException
>
> combinatorics
>        IllegalArgumentException
>        NoSuchElementException
>        UnsupportedOperationException
>
> complex
>        NumberFormatException
>        IllegalArgumentException
>
> complex-streams
>        IllegalArgumentException
>
> core
>        ArithmeticException
>        IllegalArgumentException
>
> fraction
>        ArithmeticException
>        IllegalArgumentException
>
> gamma
>        IllegalArgumentException

Some methods throw "ArithmeticException" while others throw
"IllegalArgumentException".  IIRC, my issue was whether there
were cases where the behaviour is not consistent from a
user POV (IOW, where the same behaviour would be expected).

[Note: I did not review all the packages.  But I don't recall there
were this kind of issue.]

Gilles


>
> primes
>        IllegalArgumentException
>
> quaternion
>        NumberFormatException
>        IllegalArgumentException
>        IllegalStateException
>
> rootfinder
>        IllegalArgumentException
>
>
> Nothing in this list strikes me as being inconsistent. The types are all
> standard JDK exception types and seem to be used appropriately, IMO. Is
> there any work that needs to be done on this issue?
>
> Regards,
> Matt J

>
>
>

-
To unsubscribe, e-mail: dev-unsubscr...@commons.apache.org
For additional commands, e-mail: dev-h...@commons.apache.org



-
To unsubscribe, e-mail: dev-unsubscr...@commons.apache.org
For additional commands, e-mail: dev-h...@commons.apache.org



Re: [commons-codec] branch master updated: Change AssertionError to IllegalStateException

2019-12-28 Thread Miguel Munoz
 I can't look at the code right now, but I would use an IllegalStateException 
if the problem is caused by a user error. I would use an AssertionError if the 
problem is caused by a defect in the implementation. 

-- Miguel Muñoz
 On Friday, December 27, 2019, 5:45:58 PM PST, Gary Gregory 
 wrote:  
 
 On Fri, Dec 27, 2019 at 8:17 PM  wrote:

> This is an automated email from the ASF dual-hosted git repository.
>
> aherbert pushed a commit to branch master
> in repository https://gitbox.apache.org/repos/asf/commons-codec.git
>
>
> The following commit(s) were added to refs/heads/master by this push:
>      new 1cf4d19  Change AssertionError to IllegalStateException
> 1cf4d19 is described below
>
> commit 1cf4d19069c64d0493f8b92178ffdb728c0c0ac2
> Author: Alex Herbert 
> AuthorDate: Sat Dec 28 01:17:17 2019 +
>
>    Change AssertionError to IllegalStateException
> ---
>  src/main/java/org/apache/commons/codec/digest/MurmurHash3.java | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git
> a/src/main/java/org/apache/commons/codec/digest/MurmurHash3.java
> b/src/main/java/org/apache/commons/codec/digest/MurmurHash3.java
> index d4a95ea..5d9aa9d 100644
> --- a/src/main/java/org/apache/commons/codec/digest/MurmurHash3.java
> +++ b/src/main/java/org/apache/commons/codec/digest/MurmurHash3.java
> @@ -1054,7 +1054,7 @@ public final class MurmurHash3 {
>                      k = orBytes(unprocessed[0], unprocessed[1],
> unprocessed[2], data[offset]);
>                      break;
>                  default:
> -                    throw new AssertionError("Unprocessed length should
> be 1, 2, or 3: " + unprocessedLength);
> +                    throw new IllegalStateException("Unprocessed length
> should be 1, 2, or 3: " + unprocessedLength);
>                  }
>                  hash = mix32(k, hash);
>                  // Update the offset and length
>

That seems clearer, thanks.

This seems like the kind of code we might want fuzz test. It seems
quite unlikely otherwise we'd hit this case. I also wonder if

Thoughts?

I see in several places:

// Note: This fails to apply masking using 0xL to the seed.

Shouldn't this be in the Javadoc?

Gary
  

[lang3] Proposed new class for faster equals using Reflection

2019-09-27 Thread Miguel Munoz
I created a JIra issue (LANG-1493) to propose a new class that can do a equals 
and hash code much faster than EqualsBuilder. It would not work as a drop-in 
replacement however. It would need a new API. I'm a new contributor, so I'm not 
entirely sure if this is the best way to propose a new class, but here goes.

The approach I take is to do all the reflection when the class is loaded, 
rather than when the equals method is called. This lets me perform equals test 
up to 20 times faster in my performance tests. 

You can look at a current version of my class, including unit tests, on my 
github account:

https://github.com/SwingGuy1024/DogTags

It's still a work in progress, but the current version works and is ready to 
try out.

-- Miguel Muñoz

-
To unsubscribe, e-mail: dev-unsubscr...@commons.apache.org
For additional commands, e-mail: dev-h...@commons.apache.org



[lang] New approach to tackle issue LANG-332: EqualsBuilder to alternatively use method properties

2019-06-02 Thread Miguel Munoz
I have a new approach to write a reflection-equals utility that will likely 
execute noticeably faster than the current approach. It will also let us add 
new strategies, such as an EqualsBuilder to use method properties, as requested 
in issue LANG-332. It will also allow us to add whatever other new strategies 
developers may propose.
A class that uses my new approach to determine equality and return hash codes 
might look something like this:
     public class Widget implements Comparable {         // Fields, 
properties, and methods go here           private static final 
Reflector reflector = Reflector.buildPropertyReflector(Widget.class)    
             .includeTransientProperties(trPropertyName1, trPropertyName2)      
           .exclude(propertyName1)                 .build();
           @Override public boolean equals(Object other) {             return 
reflector.doEquals(this, other);         }           @Override public int 
hashCode() {             return reflector.doHashCode(this);         }     }

There are three main advantages to doing it this way:
1. By creating the reflector class at class-load time, we speed up the process 
of comparing the instances. With the current EqualsBuilder class, much of the 
work to implement equals() gets duplicated each time it gets called.
2. It simplifies the user's task of writing the equals method. The user no 
longer needs to start each equals() method like this:
  public boolean equals(Object obj) {        if (obj == null) { return false; } 
      if (obj == this) { return true; }        if (obj.getClass() != 
getClass()) {        return false;                          }      ...  }       
                           
  Instead, all this work will be done in the call to reflector.doEquals(this, 
other)
3. The approach will make it easier to add new strategies. The example above 
calls the buildPropertyReflector() method. Other methods may be written to 
implement other approaches. For example, another strategy could be added that 
would also generate a compareTo() method, to implement the Comparable 
implementation that's consistent with equals() and hashCode(). This would 
probably involve annotations that can be used to specify the comparison order 
of the various fields or properties.
I've written a class like this before, so I know it works, and I know the 
pitfalls. In short, I would like you to assign the LANG-332 task to me.
-- Miguel Muñoz