LANG-1093: Add ClassUtils.getAbbreviatedName(). This fixes #48 from github. Thanks to Fabian Lange.
git-svn-id: https://svn.apache.org/repos/asf/commons/proper/lang/trunk@1666362 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
ce7f4ed073
commit
d38919fcbd
|
@ -22,6 +22,7 @@
|
||||||
<body>
|
<body>
|
||||||
|
|
||||||
<release version="3.4" date="tba" description="tba">
|
<release version="3.4" date="tba" description="tba">
|
||||||
|
<action issue="LANG-1093" type="add" dev="britter" due-to="Fabian Lange">Add ClassUtils.getAbbreviatedName()</action>
|
||||||
<action issue="LANG-1090" type="fix" dev="sebb">FastDateParser does not set error indication in ParsePosition</action>
|
<action issue="LANG-1090" type="fix" dev="sebb">FastDateParser does not set error indication in ParsePosition</action>
|
||||||
<action issue="LANG-1089" type="fix" dev="sebb">FastDateParser does not handle excess hours as per SimpleDateFormat</action>
|
<action issue="LANG-1089" type="fix" dev="sebb">FastDateParser does not handle excess hours as per SimpleDateFormat</action>
|
||||||
<action issue="LANG-1061" type="fix" dev="sebb" due-to="dmeneses">FastDateParser error - timezones not handled correctly</action>
|
<action issue="LANG-1061" type="fix" dev="sebb" due-to="dmeneses">FastDateParser error - timezones not handled correctly</action>
|
||||||
|
|
|
@ -314,6 +314,87 @@ public class ClassUtils {
|
||||||
return className.substring(0, i);
|
return className.substring(0, i);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Abbreviated name
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
/**
|
||||||
|
* <p>Gets the abbreviated name of a {@code Class}.</p>
|
||||||
|
*
|
||||||
|
* @param cls the class to get the abbreviated name for, may be {@code null}
|
||||||
|
* @param len the desired length of the abbreviated name
|
||||||
|
* @return the abbreviated name or an empty string
|
||||||
|
* @throws IllegalArgumentException if len <= 0
|
||||||
|
* @see getAbbreviatedName(String, int)
|
||||||
|
* @since 3.4
|
||||||
|
*/
|
||||||
|
public static String getAbbreviatedName(final Class<?> cls, int len) {
|
||||||
|
if (cls == null) {
|
||||||
|
return StringUtils.EMPTY;
|
||||||
|
}
|
||||||
|
return getAbbreviatedName(cls.getName(), len);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>Gets the abbreviated class name from a {@code String}.</p>
|
||||||
|
*
|
||||||
|
* <p>The string passed in is assumed to be a class name - it is not checked.</p>
|
||||||
|
*
|
||||||
|
* <p>The abbreviation algorithm will shorten the class name, usually without
|
||||||
|
* significant loss of meaning.</p>
|
||||||
|
* <p>The abbreviated class name will always include the complete package hierarchy.
|
||||||
|
* If enough space is available, rightmost sub-packages will be displayed in full
|
||||||
|
* length.</p>
|
||||||
|
*
|
||||||
|
* <p>The following table illustrates the algorithm:</p>
|
||||||
|
* <table>
|
||||||
|
* <tr><td>className</td><td>len</td><td>return</td></tr>
|
||||||
|
* <tr><td> null</td><td> 1</td><td>""</td></tr>
|
||||||
|
* <tr><td>"java.lang.String"</td><td> 5</td><td>"j.l.String"</td></tr>
|
||||||
|
* <tr><td>"java.lang.String"</td><td>15</td><td>"j.lang.String"</td></tr>
|
||||||
|
* <tr><td>"java.lang.String"</td><td>30</td><td>"java.lang.String"</td></tr>
|
||||||
|
* </table>
|
||||||
|
* @param className the className to get the abbreviated name for, may be {@code null}
|
||||||
|
* @param len the desired length of the abbreviated name
|
||||||
|
* @return the abbreviated name or an empty string
|
||||||
|
* @throws IllegalArgumentException if len <= 0
|
||||||
|
* @since 3.4
|
||||||
|
*/
|
||||||
|
public static String getAbbreviatedName(String className, int len) {
|
||||||
|
if (len <= 0) {
|
||||||
|
throw new IllegalArgumentException("len must be > 0");
|
||||||
|
}
|
||||||
|
if (className == null) {
|
||||||
|
return StringUtils.EMPTY;
|
||||||
|
}
|
||||||
|
|
||||||
|
int availableSpace = len;
|
||||||
|
int packageLevels = StringUtils.countMatches(className, '.');
|
||||||
|
String[] output = new String[packageLevels + 1];
|
||||||
|
int endIndex = className.length() - 1;
|
||||||
|
for (int level = packageLevels; level >= 0; level--) {
|
||||||
|
int startIndex = className.lastIndexOf('.', endIndex);
|
||||||
|
String part = className.substring(startIndex + 1, endIndex + 1);
|
||||||
|
availableSpace -= part.length();
|
||||||
|
if (level > 0) {
|
||||||
|
// all elements except top level require an additional char space
|
||||||
|
availableSpace--;
|
||||||
|
}
|
||||||
|
if (level == packageLevels) {
|
||||||
|
// ClassName is always complete
|
||||||
|
output[level] = part;
|
||||||
|
} else {
|
||||||
|
if (availableSpace > 0) {
|
||||||
|
output[level] = part;
|
||||||
|
} else {
|
||||||
|
// if no space is left still the first char is used
|
||||||
|
output[level] = part.substring(0, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
endIndex = startIndex - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return StringUtils.join(output, '.');
|
||||||
|
}
|
||||||
|
|
||||||
// Superclasses/Superinterfaces
|
// Superclasses/Superinterfaces
|
||||||
// ----------------------------------------------------------------------
|
// ----------------------------------------------------------------------
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -230,6 +230,42 @@ public class ClassUtilsTest {
|
||||||
assertEquals("", ClassUtils.getPackageName(""));
|
assertEquals("", ClassUtils.getPackageName(""));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// -------------------------------------------------------------------------
|
||||||
|
@Test
|
||||||
|
public void test_getAbbreviatedName_Class() {
|
||||||
|
assertEquals("", ClassUtils.getAbbreviatedName((Class<?>)null, 1));
|
||||||
|
assertEquals("j.l.String", ClassUtils.getAbbreviatedName(String.class, 1));
|
||||||
|
assertEquals("j.l.String", ClassUtils.getAbbreviatedName(String.class, 5));
|
||||||
|
assertEquals("j.lang.String", ClassUtils.getAbbreviatedName(String.class, 13));
|
||||||
|
assertEquals("j.lang.String", ClassUtils.getAbbreviatedName(String.class, 15));
|
||||||
|
assertEquals("java.lang.String", ClassUtils.getAbbreviatedName(String.class, 20));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test_getAbbreviatedName_Class_Exceptions() {
|
||||||
|
try {
|
||||||
|
ClassUtils.getAbbreviatedName(String.class, 0);
|
||||||
|
fail("ClassUtils.getAbbreviatedName() should fail with an "
|
||||||
|
+ "IllegalArgumentException for a len value of 0.");
|
||||||
|
} catch (final Exception e) {
|
||||||
|
assertTrue(e instanceof IllegalArgumentException);
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
ClassUtils.getAbbreviatedName(String.class, -10);
|
||||||
|
fail("ClassUtils.getAbbreviatedName() should fail with an "
|
||||||
|
+ "IllegalArgumentException for negative values of len.");
|
||||||
|
} catch (final Exception e) {
|
||||||
|
assertTrue(e instanceof IllegalArgumentException);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test_getAbbreviatedName_String() {
|
||||||
|
assertEquals("", ClassUtils.getAbbreviatedName((String)null, 1));
|
||||||
|
assertEquals("WithoutPackage", ClassUtils.getAbbreviatedName("WithoutPackage", 1));
|
||||||
|
assertEquals("j.l.String", ClassUtils.getAbbreviatedName("java.lang.String", 1));
|
||||||
|
}
|
||||||
|
|
||||||
// -------------------------------------------------------------------------
|
// -------------------------------------------------------------------------
|
||||||
@Test
|
@Test
|
||||||
public void test_getAllSuperclasses_Class() {
|
public void test_getAllSuperclasses_Class() {
|
||||||
|
|
Loading…
Reference in New Issue