commons-lang/xdocs/article2_4.xml

199 lines
17 KiB
XML
Raw Normal View History

<?xml version="1.0"?>
<!--
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<document>
<properties>
<title>What's new in 2.4?</title>
<author email="dev@commons.apache.org">Commons Documentation Team</author>
</properties>
<body>
<section name="What's new in 2.4?">
<p>Commons Lang 2.4 is out, and the obvious question is: <i>"So what? What's changed?"</i>.</p>
<p>Thus this article aims to briefly cover the changes and save you from having to dig into each JIRA
issue to see what went on in the year of development between Lang 2.3 and 2.4.</p>
<section name="Deprecations">
<p>First, let us start with a couple of deprecations. As you can see in the release notes, we chose
to deprecate the <a href="http://commons.apache.org/lang/api-release/org/apache/commons/lang/ObjectUtils.html#appendIdentityToString(java.lang.StringBuffer,%20java.lang.Object)"><code>ObjectUtils.appendIdentityToString(StringBuffer, Object)</code></a> method as its
null handling did not match its design (see <a href="http://issues.apache.org/jira/browse/LANG-360">LANG-360</a>
for more details. Instead users should use <code>ObjectUtils.identityToString(StringBuffer, Object)</code>.</p>
<p>We also deprecated <a href="http://commons.apache.org/lang/api-release/org/apache/commons/lang/time/DateUtils.html#add(java.util.Date,%20int,%20int)"><code>DateUtils.add(java.util.Date, int, int)</code></a>. It should have been <code>private</code>
from the beginning; please let us know if you actually use it.</p>
</section>
<section name="The build">
<p>Before we move on, a quick note on the build: we built 2.4 using Maven 2 and Java 1.4. We also tested that the Ant build passed the tests
successfully under Java 1.3, and that the classes compiled under Java 1.2. As it's been so long, we stopped building a Java 1.1-compatible jar. <strong>Most importantly</strong>, it <em>should</em> be a drop in replacement for Lang 2.3, but we recommend testing first, of course. Now... moving on.
</p>
</section>
<section name="New classes">
<p>Three new classes were added, so let's cover those next.</p>
<p>Firstly, we added an <a href="http://commons.apache.org/lang/api-release/org/apache/commons/lang/math/IEEE754rUtils.html"><code>IEEE754rUtils</code></a>
class to the <code>org.apache.commons.lang.math</code> package.
This candidate for ugly name of the month was needed to add <a href="http://en.wikipedia.org/wiki/IEEE_754r#min_and_max">IEEE-754r</a>
semantics for some of the <code>NumberUtils</code> methods. The relevant part of that
IEEE specification in this case is the NaN handling for <code>min</code> and <code>max</code> methods, and
you can read more about it in <a href="http://issues.apache.org/jira/browse/LANG-381">LANG-381</a>.
</p>
<p>Second and third on our newcomers list are the <a href="http://commons.apache.org/lang/api-release/org/apache/commons/lang/text/ExtendedMessageFormat.html"><code>ExtendedMessageFormat</code></a> class and its peer
<a href="http://commons.apache.org/lang/api-release/org/apache/commons/lang/text/FormatFactory.html"><code>FormatFactory</code></a>
interface, both found in the <code>org.apache.commons.lang.text</code> package.</p>
<p>Together they allow you to take the <code>java.text.MessageFormat</code> class further and insert your own formatting elements.</p>
<p>
By way of an example, imagine that we have a need for custom formatting of a employee identification
number or EIN. Perhaps, simplistically, our EIN is composed of a two-character department code
followed by a four-digit number, and that it is customary within our organization to render the EIN
with a hyphen following the department identifier. Here we'll represent the EIN as a simple
String (of course in real life we would likely create a class composed of department and number).
We can create a custom <code>Format</code> class:
<pre><code>
public class EINFormat extends Format {
private char[] idMask;
public EINFormat() {
}
public EINFormat(char maskChar) {
idMask = new char[4];
Arrays.fill(idMask, maskChar);
}
public StringBuffer format(Object obj, StringBuffer toAppendTo, FieldPosition pos) {
String ein = (String) obj; //assume or assert length &gt;= 2
if (idMask == null) {
return new StringBuffer(ein).insert(2, '-').toString();
}
return new StringBuffer(ein.substring(0, 2)).append('-').append(idMask).toString();
}
public Object parseObject(String source, ParsePosition pos) {
int idx = pos.getIndex();
int endIdx = idx + 7;
if (source == null || source.length() &lt; endIdx) {
pos.setErrorIndex(idx);
return null;
}
if (source.charAt(idx + 2) != '-') {
pos.setErrorIndex(idx);
return null;
}
pos.setIndex(endIdx);
return source.substring(idx, endIdx).deleteCharAt(2);
}
}
</code></pre>
Our custom EIN format is made available for <code>MessageFormat</code>-style processing by a
<code>FormatFactory</code> implementation:
<pre><code>
public class EINFormatFactory implements FormatFactory {
public static final String EIN_FORMAT = "ein";
public Format getFormat(String name, String arguments, Locale locale) {
if (EIN_FORMAT.equals(name)) {
if (arguments == null || "".equals(arguments)) {
return new EINFormat();
}
return new EINFormat(arguments.charAt(0));
}
return null;
}
}
</code></pre>
Now you simply provide a <code>java.util.Map&lt;String, FormatFactory&gt;</code> registry (keyed
by format type) to <code>ExtendedMessageFormat</code>:
<pre><code>
new ExtendedMessageFormat("EIN: {0,ein}", Collections.singletonMap(EINFormatFactory.EIN_FORMAT, new EINFormatFactory()));
</code></pre>
As expected, this will render a String EIN "AA-9999" as: <code>"EIN: AA-9999"</code>.
<br />
If we wanted to trigger the EIN masking code, we could trigger that in the format pattern:
<pre><code>
new ExtendedMessageFormat("EIN: {0,ein,#}", Collections.singletonMap(EINFormatFactory.EIN_FORMAT, new EINFormatFactory()));
</code></pre>
This should render "AA-9999" as: <code>"EIN: AA-####"</code>.
</p>
<p>
You can also use <code>ExtendedMessageFormat</code> to override any or all of the built-in
formats supported by <code>java.text.MessageFormat</code>. Finally, note that because
<code>ExtendedMessageFormat</code> extends <code>MessageFormat</code> it should work in most
cases as a <em>true</em> drop-in replacement.
</p>
</section>
<section name="New methods">
<p>There were 58 new methods added to existing Commons Lang classes. Going through each one, one at a time would be dull,
and fortunately there are some nice groupings that we can discuss instead:</p>
<p><b>CharSet getInstance(String[])</b> adds an additional builder method by which you can build a CharSet from multiple sets of characters at the same time. If you weren't aware of the CharSet class, it holds a set of characters created by a simple pattern language allowing constructs such as <code>"a-z"</code> and <code>"^a"</code> (everything but 'a'). It's most used by the CharSetUtils class, and came out of CharSetUtils.translate, a simple variant of the UNIX tr command.
<a href="http://commons.apache.org/lang/api-release/org/apache/commons/lang/CharSet.html#getInstance(java.lang.String[])"><img src="/images/external.png"/></a></p>
<p><b>ClassUtils Canonical name methods</b> are akin to the non '<code>Canonical</code>' methods, except they work with the more human readable <code>int[]</code> type names rather than the JVM versions of <code>[I</code>. This makes them useful for parsing input from developer's configuration files.
<a href="http://commons.apache.org/lang/api-release/org/apache/commons/lang/ClassUtils.html"><img src="/images/external.png"/></a></p>
<p><b>ClassUtils toClass(String[])</b> is very easy to explain - it calls <code>toClass</code> on each <code>Object</code> in the array and returns an array of <code>Class</code> objects.
<a href="http://commons.apache.org/lang/api-release/org/apache/commons/lang/ClassUtils.html#toClass(java.lang.Object[])"><img src="/images/external.png"/></a></p>
<p><b>ClassUtils wrapper-&gt;primitive conversions</b> are the reflection of the pre-existing <code>primitiveToWrapper</code> methods. Again easy to explain, they turn an array of <code>Integer</code> into an array of <code>int[]</code>.
<a href="http://commons.apache.org/lang/api-release/org/apache/commons/lang/ClassUtils.html#wrappersToPrimitives(java.lang.Class[])"><img src="/images/external.png"/></a></p>
<p><b>ObjectUtils identityToString(StringBuffer, Object)</b> is the StringBuffer variant of the pre-existing <code>identityToString</code> method. In case you've not met that before, it produces the toString that would have been produced by an Object if it hadn't been overridden.
<a href="http://commons.apache.org/lang/api-release/org/apache/commons/lang/ObjectUtils.html#identityToString(java.lang.StringBuffer,%20java.lang.Object)"><img src="/images/external.png"/></a></p>
<p><b>StringEscapeUtils CSV methods</b> are a new addition to our range of simple parser/printers. These, quite as expected, parse and unparse CSV text as per <a href="http://tools.ietf.org/html/rfc4180">RFC-4180</a>.
<a href="http://commons.apache.org/lang/api-release/org/apache/commons/lang/StringEscapeUtils.html#escapeCsv(java.lang.String)"><img src="/images/external.png"/></a></p>
<p><b>StringUtils</b> has a host of new methods, as always, and we'll leave these for later.</p>
<p><b>WordUtils abbreviate</b> finds the first space after the lower limit and abbreviates the text.
<a href="http://commons.apache.org/lang/api-release/org/apache/commons/lang/WordUtils.html#abbreviate(java.lang.String,%20int,%20int,%20java.lang.String)"><img src="/images/external.png"/></a></p>
<p><b>math.IntRange/LongRange.toArray</b> turn the range into an array of primitive <code>int</code>/<code>long</code>s contained in the range.
<a href="http://commons.apache.org/lang/api-release/org/apache/commons/lang/math/IntRange.html#toArray()"><img src="/images/external.png"/></a>,
<a href="http://commons.apache.org/lang/api-release/org/apache/commons/lang/math/LongRange.html#toArray()"><img src="/images/external.png"/></a></p>
<p><b>text.StrMatch.isMatch(char[], int)</b> is a helper method for checking whether there was a match with the StrMatcher objects.
<a href="http://commons.apache.org/lang/api-release/org/apache/commons/lang/text/StrMatcher.html#isMatch(char[],%20int)"><img src="/images/external.png"/></a></p>
<p><b>time.DateFormatUtils format(Calendar, ...)</b> provide Calendar variants for the pre-existing format methods. If these are new to you, they are helper methods to formatting a date.
<a href="http://commons.apache.org/lang/api-release/org/apache/commons/lang/time/DateFormatUtils.html"><img src="/images/external.png"/></a></p>
<p><b>time.DateUtils getFragment* methods</b> are used to splice the time element out of Date. If you have <code>2008/12/13 14:57</code>, then these could, for example, pull out the 13.
<a href="http://commons.apache.org/lang/api-release/org/apache/commons/lang/time/DateUtils.html"><img src="/images/external.png"/></a></p>
<p><b>time.DateUtils setXxx methods</b> round off our walk through the methods - the setXxx variant of the existing addXxx helper methods.
<a href="http://commons.apache.org/lang/api-release/org/apache/commons/lang/time/DateUtils.html"><img src="/images/external.png"/></a></p>
</section>
<section name="StringUtils methods">
<p>The <code>StringUtils</code> class is a little large, isn't it? Sorry, but it's gotten bigger.
</p>
<ul>
<li>boolean containsAny(String, char[]) <a href="http://commons.apache.org/lang/api-release/org/apache/commons/lang/StringUtils.html#containsOnly(java.lang.String,%20char[])"><img src="/images/external.png"/></a></li>
<li>boolean containsAny(String, String) <a href="http://commons.apache.org/lang/api-release/org/apache/commons/lang/StringUtils.html#containsOnly(java.lang.String,%20java.lang.String)"><img src="/images/external.png"/></a></li>
<li>boolean endsWith(String, String) <a href="http://commons.apache.org/lang/api-release/org/apache/commons/lang/StringUtils.html#endsWith(java.lang.String,%20java.lang.String)"><img src="/images/external.png"/></a></li>
<li>boolean endsWithIgnoreCase(String, String) <a href="http://commons.apache.org/lang/api-release/org/apache/commons/lang/StringUtils.html#endsWithIgnoreCase(java.lang.String,%20java.lang.String)"><img src="/images/external.png"/></a></li>
<li>String getCommonPrefix(String[]) <a href="http://commons.apache.org/lang/api-release/org/apache/commons/lang/StringUtils.html#getCommonPrefix(java.lang.String[])"><img src="/images/external.png"/></a></li>
<li>int indexOfDifference(String[]) <a href="http://commons.apache.org/lang/api-release/org/apache/commons/lang/StringUtils.html#indexOfDifference(java.lang.String[])"><img src="/images/external.png"/></a></li>
<li>int length(String) <a href="http://commons.apache.org/lang/api-release/org/apache/commons/lang/StringUtils.html#length(java.lang.String)"><img src="/images/external.png"/></a></li>
<li>String removeEndIgnoreCase(String, String) <a href="http://commons.apache.org/lang/api-release/org/apache/commons/lang/StringUtils.html#removeEndIgnoreCase(java.lang.String,%20java.lang.String)"><img src="/images/external.png"/></a></li>
<li>String removeStartIgnoreCase(String, String) <a href="http://commons.apache.org/lang/api-release/org/apache/commons/lang/StringUtils.html#removeStartIgnoreCase(java.lang.String,%20java.lang.String)"><img src="/images/external.png"/></a></li>
<li>String replaceEach(String, String[], String[]) <a href="http://commons.apache.org/lang/api-release/org/apache/commons/lang/StringUtils.html#replaceEach(java.lang.String,%20java.lang.String[],%20java.lang.String[])"><img src="/images/external.png"/></a></li>
<li>String replaceEachRepeatedly(String, String[], String[]) <a href="http://commons.apache.org/lang/api-release/org/apache/commons/lang/StringUtils.html#replaceEachRepeatedly(java.lang.String,%20java.lang.String[],%20java.lang.String[])"><img src="/images/external.png"/></a></li>
<li>String[] splitByCharacterType(String) <a href="http://commons.apache.org/lang/api-release/org/apache/commons/lang/StringUtils.html#splitByCharacterType(java.lang.String)"><img src="/images/external.png"/></a></li>
<li>String[] splitByCharacterTypeCamelCase(String) <a href="http://commons.apache.org/lang/api-release/org/apache/commons/lang/StringUtils.html#splitByCharacterTypeCamelCase(java.lang.String)"><img src="/images/external.png"/></a></li>
<li>String[] splitByWholeSeparatorPreserveAllTokens(String, String) <a href="http://commons.apache.org/lang/api-release/org/apache/commons/lang/StringUtils.html#splitByWholeSeparatorPreserveAllTokens(java.lang.String,%20java.lang.String)"><img src="/images/external.png"/></a></li>
<li>String[] splitByWholeSeparatorPreserveAllTokens(String, String, int) <a href="http://commons.apache.org/lang/api-release/org/apache/commons/lang/StringUtils.html#splitByWholeSeparatorPreserveAllTokens(java.lang.String,%20java.lang.String,%20int)"><img src="/images/external.png"/></a></li>
<li>boolean startsWith(String, String) <a href="http://commons.apache.org/lang/api-release/org/apache/commons/lang/StringUtils.html#startsWith(java.lang.String,%20java.lang.String)"><img src="/images/external.png"/></a></li>
<li>boolean startsWithIgnoreCase(String, String) <a href="http://commons.apache.org/lang/api-release/org/apache/commons/lang/StringUtils.html#startsWithIgnoreCase(java.lang.String,%20java.lang.String)"><img src="/images/external.png"/></a></li>
</ul>
<p>Hopefully they are in many cases self-describing. Rather than spend a lot of time describing them, we'll let you read the Javadoc of the ones that interest you.</p>
</section>
<section name="So long, farewell...">
<p>Hopefully that was of interest. Don't forget to download <a href="download_lang.cgi">Lang 2.4</a>, or, for the Maven repository users, upgrade your &lt;version&gt; tag to 2.4. Please feel free to raise any questions you might have on the <a href="mail-lists.html">mailing lists</a>, and report bugs or enhancements in the <a href="issue-tracking.html">issue tracker</a>.</p>
</section>
</section>
</body>
</document>