Author: tchemit Date: 2011-01-29 14:50:52 +0100 (Sat, 29 Jan 2011) New Revision: 1042 Url: http://nuiton.org/repositories/revision/eugene/1042 Log: Evolution #1268: Improve importManager Evolution #1273: Add usefull method in JavaGeneratorUtil to deal with generics Added: trunk/eugene/src/test/java/org/nuiton/eugene/java/JavaGeneratorUtilTest.java Modified: trunk/eugene/src/main/java/org/nuiton/eugene/java/JavaGeneratorUtil.java trunk/eugene/src/main/java/org/nuiton/eugene/java/extension/ImportsManager.java trunk/eugene/src/test/java/org/nuiton/eugene/java/extension/ImportsManagerTest.java Modified: trunk/eugene/src/main/java/org/nuiton/eugene/java/JavaGeneratorUtil.java =================================================================== --- trunk/eugene/src/main/java/org/nuiton/eugene/java/JavaGeneratorUtil.java 2011-01-29 07:20:31 UTC (rev 1041) +++ trunk/eugene/src/main/java/org/nuiton/eugene/java/JavaGeneratorUtil.java 2011-01-29 13:50:52 UTC (rev 1042) @@ -34,6 +34,9 @@ import org.nuiton.eugene.models.object.ObjectModelOperation; import org.nuiton.eugene.models.object.ObjectModelParameter; +import java.util.ArrayList; +import java.util.List; + /** * Utility class for pure java templates. * @@ -174,4 +177,208 @@ String value = findTagValue(EugeneTagValues.TAG_CONSTANT_PREFIX, classifier, model); return value; } + + /** + * Split the given fqn which contains a generic declaration into his parts. + * <p/> + * Example : + * <pre> + * java.util.List<Integer> : [java.util.List, Integer] + * java.util.List<java.util.List<Integer>> : [java.util.List, java.util.List<Integer>] + * java.util.Map<Integer, Integer> : [java.util.Map, Integer, Integer] + * java.util.Map<Integer, java.util.List<Integer>> : [java.util.Map, Integer, java.util.List<Integer>] + * <p/> + * </pre> + * <strong>Note:</strong> We only deal with one level of generics here in + * order to be able easly to rebuild after all the fqn with simple names... + * + * @param fqn the fqn to split + * @return the array of all parts of the fqn. + * @since 2.3.2 + */ + public static String[] splitGeneric(String fqn) { + if (fqn == null) { + return null; + } + + int firstPartIndex = fqn.indexOf('<'); + if (firstPartIndex == -1) { + + // no generics, just return the fqn + return new String[]{fqn}; + } + + List<String> parts = new ArrayList<String>(); + parts.add(fqn.substring(0, firstPartIndex)); + String rest = fqn.substring(firstPartIndex + 1, + fqn.lastIndexOf('>')); + + if (containsGenerics(rest) && rest.contains(",")) { + + // there is others generics in generics, worse case... + int begin = 0; + int count = 0; + int max = rest.length(); + for (int i = 0; i < max; i++) { + char c = rest.charAt(i); + if (c == '<') { + + count++; + } else if (c == '>') { + + count--; + } else if (c == ',') { + + // arrives on a possible split + if (count == 0) { + + // can safely add this part + String part = rest.substring(begin, i); + parts.add(part.trim()); + begin = i + 1; + } + } + } + + // there is a last part to add ? + if (begin < max) { + String part = rest.substring(begin, max); + parts.add(part.trim()); + } + + } else { + + // simple case : each part of the generics has no other generics + String[] split = rest.split(","); + for (String part : split) { + parts.add(part.trim()); + } + } + + return parts.toArray(new String[parts.size()]); + } + + /** + * Join generics parts of a fqn into aparts. + * <p/> + * Example : + * <pre> + * [java.util.List, Integer] : java.util.List<Integer> + * [java.util.List, java.util.List<Integer>] : java.util.List<java.util.List<Integer>> + * [java.util.Map, Integer, Integer] : java.util.Map<Integer, Integer> + * [java.util.Map, Integer, java.util.List<Integer>] : java.util.Map<Integer, java.util.List<Integer>> + * </pre> + * + * @param genericParts the parts of fqn + * @return the fqn from his parts + * @since 2.3.2 + */ + public static String joinGeneric(String... genericParts) { + + if (genericParts == null || genericParts.length == 0) { + + // this case should never happen ? + return null; + } + + if (genericParts.length == 1) { + + // in fact, no generics + return genericParts[0]; + } + + StringBuilder sb = new StringBuilder(genericParts[0]); + + sb.append("<").append(genericParts[1]); + + for (int i = 2, max = genericParts.length; i < max; i++) { + String genericPart = genericParts[i]; + sb.append(", ").append(genericPart); + } + sb.append('>'); + return sb.toString(); + } + + /** + * Tells if the given fqn contains a generic declaration (says contains a + * {@code <} caracter). + * + * @param fqn the fqn to test + * @return {@code true} if given fqn contains a generic declaration + * @since 2.3.2 + */ + public static boolean containsGenerics(String fqn) { + return fqn.contains("<"); + } + + /** + * Split the given fqns gieven the list separator. + * <p/> + * Example : + * <pre> + * Boolean, File : [Boolean, File] + * Boolean , java.util.List<Integer> : [Boolean, java.util.List<Integer>] + * <p/> + * </pre> + * <p/> + * <strong>Note:</strong> You can NOT use as separator {@code '<'} nor + * {@code '>'} nor {@code ' '}. + * + * @param fqns the fqn list to split + * @param separator the fqn separactor char + * @return the array of all parts of the fqn. + * @since 2.3.2 + */ + public static String[] splitFqnList(String fqns, char separator) { + if (separator == '<' || separator == '>' || separator == ' ') { + throw new IllegalArgumentException( + "Can not use '<' nor '>' for the separator"); + } + if (fqns == null) { + return null; + } + + int firstPartIndex = fqns.indexOf('<'); + if (firstPartIndex == -1) { + + // no generics, just return the fqn + return new String[]{fqns}; + } + + List<String> parts = new ArrayList<String>(); + + + // there is others generics in generics, worse case... + int begin = 0; + int count = 0; + int max = fqns.length(); + for (int i = 0; i < max; i++) { + char c = fqns.charAt(i); + if (c == '<') { + + count++; + } else if (c == '>') { + + count--; + } else if (c == separator) { + + // arrives on a possible split + if (count == 0) { + + // can safely add this part + String part = fqns.substring(begin, i); + parts.add(part.trim()); + begin = i + 1; + } + } + } + + // there is a last part to add ? + if (begin < max) { + String part = fqns.substring(begin, max); + parts.add(part.trim()); + } + + return parts.toArray(new String[parts.size()]); + } } Modified: trunk/eugene/src/main/java/org/nuiton/eugene/java/extension/ImportsManager.java =================================================================== --- trunk/eugene/src/main/java/org/nuiton/eugene/java/extension/ImportsManager.java 2011-01-29 07:20:31 UTC (rev 1041) +++ trunk/eugene/src/main/java/org/nuiton/eugene/java/extension/ImportsManager.java 2011-01-29 13:50:52 UTC (rev 1042) @@ -27,6 +27,7 @@ import org.apache.commons.lang.StringUtils; import org.nuiton.eugene.GeneratorUtil; +import org.nuiton.eugene.java.JavaGeneratorUtil; import java.util.ArrayList; import java.util.Collections; @@ -125,10 +126,10 @@ if (primitiveTypes.contains(fqn)) { return true; } - if (containsGenerics(fqn)) { + if (JavaGeneratorUtil.containsGenerics(fqn)) { // Generics case : - String[] parts = splitGeneric(fqn); + String[] parts = JavaGeneratorUtil.splitGeneric(fqn); for (String part : parts) { if (addImport(part)) { return true; @@ -170,14 +171,14 @@ // There is a conflict, do not use simple name return fqn; } - if (containsGenerics(fqn)) { + if (JavaGeneratorUtil.containsGenerics(fqn)) { - String[] parts = splitGeneric(fqn); + String[] parts = JavaGeneratorUtil.splitGeneric(fqn); for (int i = 0; i < parts.length; i++) { String part = parts[i]; parts[i] = getType(part); } - return joinGeneric(parts); + return JavaGeneratorUtil.joinGeneric(parts); } // No conflict, use simple name int packageEndIndex = getLastDotIndex(fqn); @@ -192,7 +193,7 @@ if (StringUtils.isBlank(returnType)) { return null; } - if (containsGenerics(returnType)) { + if (JavaGeneratorUtil.containsGenerics(returnType)) { // the return type is in two parts : <...> ... String[] parts = @@ -253,139 +254,6 @@ } /** - * Split the given fqn which contains a generic declaration into his parts. - * <p/> - * Example : - * <pre> - * java.util.List<Integer> : [java.util.List, Integer] - * java.util.List<java.util.List<Integer>> : [java.util.List, java.util.List<Integer>] - * java.util.Map<Integer, Integer> : [java.util.Map, Integer, Integer] - * java.util.Map<Integer, java.util.List<Integer>> : [java.util.Map, Integer, java.util.List<Integer>] - * <p/> - * </pre> - * <strong>Note:</strong> We only deal with one level of generics here in - * order to be able easly to rebuild after all the fqn with simple names... - * - * @param fqn the fqn to split - * @return the array of all parts of the fqn. - * @since 2.3.2 - */ - public String[] splitGeneric(String fqn) { - if (fqn == null) { - return null; - } - - int firstPartIndex = fqn.indexOf('<'); - if (firstPartIndex == -1) { - - // no generics, just return the fqn - return new String[]{fqn}; - } - - List<String> parts = new ArrayList<String>(); - parts.add(fqn.substring(0, firstPartIndex)); - String rest = fqn.substring(firstPartIndex + 1, - fqn.lastIndexOf('>')); - - if (containsGenerics(rest) && rest.contains(",")) { - - // there is others generics in generics, worse case... - int begin = 0; - int count = 0; - int max = rest.length(); - for (int i = 0; i < max; i++) { - char c = rest.charAt(i); - if (c == '<') { - - count++; - } else if (c == '>') { - - count--; - } else if (c == ',') { - - // arrives on a possible split - if (count == 0) { - - // can safely add this part - String part = rest.substring(begin, i); - parts.add(part.trim()); - begin = i + 1; - } - } - } - - // there is a last part to add ? - if (begin < max) { - String part = rest.substring(begin, max); - parts.add(part.trim()); - } - - } else { - - // simple case : each part of the generics has no other generics - String[] split = rest.split(","); - for (String part : split) { - parts.add(part.trim()); - } - } - - return parts.toArray(new String[parts.size()]); - } - - /** - * Join generics parts of a fqn into aparts. - * <p/> - * Example : - * <pre> - * [java.util.List, Integer] : java.util.List<Integer> - * [java.util.List, java.util.List<Integer>] : java.util.List<java.util.List<Integer>> - * [java.util.Map, Integer, Integer] : java.util.Map<Integer, Integer> - * [java.util.Map, Integer, java.util.List<Integer>] : java.util.Map<Integer, java.util.List<Integer>> - * </pre> - * - * @param genericParts the parts of fqn - * @return the fqn from his parts - * @since 2.3.2 - */ - public String joinGeneric(String... genericParts) { - - if (genericParts == null || genericParts.length == 0) { - - // this case should never happen ? - return null; - } - - if (genericParts.length == 1) { - - // in fact, no generics - return genericParts[0]; - } - - StringBuilder sb = new StringBuilder(genericParts[0]); - - sb.append("<").append(genericParts[1]); - - for (int i = 2, max = genericParts.length; i < max; i++) { - String genericPart = genericParts[i]; - sb.append(", ").append(genericPart); - } - sb.append('>'); - return sb.toString(); - } - - /** - * Tells if the given fqn contains a generic declaration (says contains a - * {@code <} caracter). - * - * @param fqn the fqn to test - * @return {@code true} if given fqn contains a generic declaration - * @since 2.3.2 - */ - public boolean containsGenerics(String fqn) { - return fqn.contains("<"); - } - - /** * Obtains the last dot index in the given fqn. * * @param fqn the fqn to test Added: trunk/eugene/src/test/java/org/nuiton/eugene/java/JavaGeneratorUtilTest.java =================================================================== --- trunk/eugene/src/test/java/org/nuiton/eugene/java/JavaGeneratorUtilTest.java (rev 0) +++ trunk/eugene/src/test/java/org/nuiton/eugene/java/JavaGeneratorUtilTest.java 2011-01-29 13:50:52 UTC (rev 1042) @@ -0,0 +1,129 @@ +package org.nuiton.eugene.java; + +import org.junit.Assert; +import org.junit.Test; +import org.nuiton.util.StringUtil; + +/** + * Test class {@link JavaGeneratorUtil}. + * + * @author tchemit <chemit@codelutin.com> + * @since 2.3.2 + */ +public class JavaGeneratorUtilTest { + + @Test + public void splitGeneric() throws Exception { + + String[] actual; + String[] expected; + + expected = null; + actual = JavaGeneratorUtil.splitGeneric(null); + Assert.assertArrayEquals(expected, actual); + + expected = new String[]{"java.util.List"}; + actual = JavaGeneratorUtil.splitGeneric("java.util.List"); + Assert.assertArrayEquals(expected, actual); + + expected = new String[]{"java.util.List", "Integer"}; + actual = JavaGeneratorUtil.splitGeneric("java.util.List<Integer>"); + Assert.assertArrayEquals(expected, actual); + + expected = new String[]{"java.util.List", "java.util.List<Integer>"}; + actual = JavaGeneratorUtil.splitGeneric("java.util.List<java.util.List<Integer>>"); + Assert.assertArrayEquals(expected, actual); + + expected = new String[]{"java.util.Map", "Integer", "Integer"}; + actual = JavaGeneratorUtil.splitGeneric("java.util.Map<Integer, Integer>"); + Assert.assertArrayEquals(expected, actual); + + expected = new String[]{"java.util.Map", "Integer", "java.util.List<Integer>"}; + actual = JavaGeneratorUtil.splitGeneric("java.util.Map<Integer, java.util.List<Integer>>"); + Assert.assertArrayEquals(expected, actual); + + expected = new String[]{"java.util.Map", "Integer", "java.util.Map<Integer, Integer>"}; + actual = JavaGeneratorUtil.splitGeneric("java.util.Map<Integer, java.util.Map<Integer, Integer>>"); + Assert.assertArrayEquals(expected, actual); + + expected = new String[]{"java.util.Map", "Integer", "java.util.Map<Integer, Integer, Toto<A, B, C>>", "X", "Y<X>"}; + actual = JavaGeneratorUtil.splitGeneric("java.util.Map<Integer, java.util.Map<Integer, Integer, Toto<A, B, C>>, X, Y<X>>"); + Assert.assertArrayEquals(expected, actual); + + expected = new String[]{"java.util.Map", "X<Y<Z>>", "java.util.Map<Integer, Integer, Toto<A, B, C>>", "X", "Y<X>"}; + actual = JavaGeneratorUtil.splitGeneric("java.util.Map< X<Y<Z>>, java.util.Map<Integer, Integer, Toto<A, B, C>>, X, Y<X>>"); + Assert.assertArrayEquals(expected, actual); + } + + + @Test + public void joinGeneric() throws Exception { + String actual; + String expected; + + expected = null; + actual = JavaGeneratorUtil.joinGeneric((String) null); + Assert.assertEquals(expected, actual); + + expected = null; + actual = JavaGeneratorUtil.joinGeneric(StringUtil.EMPTY_STRING_ARRAY); + Assert.assertEquals(expected, actual); + + expected = "java.util.List"; + actual = JavaGeneratorUtil.joinGeneric("java.util.List"); + Assert.assertEquals(expected, actual); + + expected = "java.util.List<Integer>"; + actual = JavaGeneratorUtil.joinGeneric("java.util.List", "Integer"); + Assert.assertEquals(expected, actual); + + + expected = "java.util.List<java.util.List<Integer>>"; + actual = JavaGeneratorUtil.joinGeneric("java.util.List", "java.util.List<Integer>"); + Assert.assertEquals(expected, actual); + + expected = "java.util.Map<Integer, Integer>"; + actual = JavaGeneratorUtil.joinGeneric("java.util.Map", "Integer", "Integer"); + Assert.assertEquals(expected, actual); + + expected = "java.util.Map<Integer, java.util.List<Integer>>"; + actual = JavaGeneratorUtil.joinGeneric("java.util.Map", "Integer", "java.util.List<Integer>"); + Assert.assertEquals(expected, actual); + } + + @Test + public void splitFqnList() throws Exception { + + String[] actual; + String[] expected; + + expected = null; + actual = JavaGeneratorUtil.splitFqnList(null, ','); + Assert.assertArrayEquals(expected, actual); + + expected = new String[]{"java.util.List"}; + actual = JavaGeneratorUtil.splitFqnList("java.util.List", ','); + Assert.assertArrayEquals(expected, actual); + + expected = new String[]{"Integer", "java.util.List<Integer>"}; + actual = JavaGeneratorUtil.splitFqnList("Integer, java.util.List<Integer>", ','); + Assert.assertArrayEquals(expected, actual); + + expected = new String[]{"java.util.List", "java.util.List<java.util.List<Integer>>"}; + actual = JavaGeneratorUtil.splitFqnList("java.util.List, java.util.List<java.util.List<Integer>>", ','); + Assert.assertArrayEquals(expected, actual); + + expected = new String[]{"java.util.List", "java.util.Map<Integer, Integer>"}; + actual = JavaGeneratorUtil.splitFqnList("java.util.List, java.util.Map<Integer, Integer>", ','); + Assert.assertArrayEquals(expected, actual); + + + expected = new String[]{"java.util.Map< X<Y<Z>>>", "java.util.Map<Integer, Integer, Toto<A, B, C>>", "X", "Y<X>"}; + actual = JavaGeneratorUtil.splitFqnList("java.util.Map< X<Y<Z>>>, java.util.Map<Integer, Integer, Toto<A, B, C>>, X, Y<X>", ','); + Assert.assertArrayEquals(expected, actual); + + expected = new String[]{"java.util.Map< X<Y<Z>>>", "java.util.Map<Integer, Integer, Toto<A, B, C>>", "X", "Y<X>"}; + actual = JavaGeneratorUtil.splitFqnList("java.util.Map< X<Y<Z>>>| java.util.Map<Integer, Integer, Toto<A, B, C>>| X| Y<X>", '|'); + Assert.assertArrayEquals(expected, actual); + } +} Property changes on: trunk/eugene/src/test/java/org/nuiton/eugene/java/JavaGeneratorUtilTest.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL Added: svn:eol-style + native Modified: trunk/eugene/src/test/java/org/nuiton/eugene/java/extension/ImportsManagerTest.java =================================================================== --- trunk/eugene/src/test/java/org/nuiton/eugene/java/extension/ImportsManagerTest.java 2011-01-29 07:20:31 UTC (rev 1041) +++ trunk/eugene/src/test/java/org/nuiton/eugene/java/extension/ImportsManagerTest.java 2011-01-29 13:50:52 UTC (rev 1042) @@ -29,7 +29,6 @@ import org.junit.Assert; import org.junit.Before; import org.junit.Test; -import org.nuiton.util.StringUtil; import java.io.Serializable; import java.util.List; @@ -50,85 +49,6 @@ } @Test - public void splitGeneric() throws Exception { - - String[] actual; - String[] expected; - - expected = null; - actual = mgr.splitGeneric(null); - Assert.assertArrayEquals(expected, actual); - - expected = new String[]{"java.util.List"}; - actual = mgr.splitGeneric("java.util.List"); - Assert.assertArrayEquals(expected, actual); - - expected = new String[]{"java.util.List", "Integer"}; - actual = mgr.splitGeneric("java.util.List<Integer>"); - Assert.assertArrayEquals(expected, actual); - - expected = new String[]{"java.util.List", "java.util.List<Integer>"}; - actual = mgr.splitGeneric("java.util.List<java.util.List<Integer>>"); - Assert.assertArrayEquals(expected, actual); - - expected = new String[]{"java.util.Map", "Integer", "Integer"}; - actual = mgr.splitGeneric("java.util.Map<Integer, Integer>"); - Assert.assertArrayEquals(expected, actual); - - expected = new String[]{"java.util.Map", "Integer", "java.util.List<Integer>"}; - actual = mgr.splitGeneric("java.util.Map<Integer, java.util.List<Integer>>"); - Assert.assertArrayEquals(expected, actual); - - expected = new String[]{"java.util.Map", "Integer", "java.util.Map<Integer, Integer>"}; - actual = mgr.splitGeneric("java.util.Map<Integer, java.util.Map<Integer, Integer>>"); - Assert.assertArrayEquals(expected, actual); - - expected = new String[]{"java.util.Map", "Integer", "java.util.Map<Integer, Integer, Toto<A, B, C>>", "X", "Y<X>"}; - actual = mgr.splitGeneric("java.util.Map<Integer, java.util.Map<Integer, Integer, Toto<A, B, C>>, X, Y<X>>"); - Assert.assertArrayEquals(expected, actual); - - expected = new String[]{"java.util.Map", "X<Y<Z>>", "java.util.Map<Integer, Integer, Toto<A, B, C>>", "X", "Y<X>"}; - actual = mgr.splitGeneric("java.util.Map< X<Y<Z>>, java.util.Map<Integer, Integer, Toto<A, B, C>>, X, Y<X>>"); - Assert.assertArrayEquals(expected, actual); - } - - - @Test - public void joinGeneric() throws Exception { - String actual; - String expected; - - expected = null; - actual = mgr.joinGeneric((String) null); - Assert.assertEquals(expected, actual); - - expected = null; - actual = mgr.joinGeneric(StringUtil.EMPTY_STRING_ARRAY); - Assert.assertEquals(expected, actual); - - expected = "java.util.List"; - actual = mgr.joinGeneric("java.util.List"); - Assert.assertEquals(expected, actual); - - expected = "java.util.List<Integer>"; - actual = mgr.joinGeneric("java.util.List", "Integer"); - Assert.assertEquals(expected, actual); - - - expected = "java.util.List<java.util.List<Integer>>"; - actual = mgr.joinGeneric("java.util.List", "java.util.List<Integer>"); - Assert.assertEquals(expected, actual); - - expected = "java.util.Map<Integer, Integer>"; - actual = mgr.joinGeneric("java.util.Map", "Integer", "Integer"); - Assert.assertEquals(expected, actual); - - expected = "java.util.Map<Integer, java.util.List<Integer>>"; - actual = mgr.joinGeneric("java.util.Map", "Integer", "java.util.List<Integer>"); - Assert.assertEquals(expected, actual); - } - - @Test public void getReturnType() throws Exception { String actual; String expected;