11package com .telerik .metadata ;
22
33import java .io .File ;
4+ import java .lang .reflect .Array ;
5+ import java .lang .reflect .Method ;
6+ import java .net .URL ;
7+ import java .net .URLClassLoader ;
48import java .util .ArrayList ;
59import java .util .Arrays ;
610import java .util .Comparator ;
711import java .util .HashMap ;
12+ import java .util .HashSet ;
813import java .util .List ;
914import java .util .Map ;
1015
@@ -124,7 +129,9 @@ private static void setNodeMembers(ClassDescriptor clazz, TreeNode node, TreeNod
124129 }
125130
126131 MethodDescriptor [] allMethods = ClassUtil .getAllMethods (clazz );
127- MethodDescriptor [] methods = clazz .getMethods ();
132+ MethodDescriptor [] classImplementedMethods = clazz .getMethods ();
133+ MethodDescriptor [] interfaceImplementedMethods = getDefaultMethodsFromImplementedInterfaces (clazz , classImplementedMethods );
134+ MethodDescriptor [] methods = concatenate (classImplementedMethods , interfaceImplementedMethods );
128135
129136 Arrays .sort (methods , methodNameComparator );
130137
@@ -151,8 +158,8 @@ private static void setNodeMembers(ClassDescriptor clazz, TreeNode node, TreeNod
151158 && (m1 .isPublic () || m1 .isProtected ())
152159 && (isStatic == m1IsStatic )
153160 && (m1 .getName ().equals (mi .name ) && (m1
154- .getArgumentTypes ().length == m
155- .getArgumentTypes ().length ))) {
161+ .getArgumentTypes ().length == m
162+ .getArgumentTypes ().length ))) {
156163 if (++countUnique > 1 ) {
157164 break ;
158165 }
@@ -162,7 +169,7 @@ private static void setNodeMembers(ClassDescriptor clazz, TreeNode node, TreeNod
162169
163170 TypeDescriptor [] params = m .getArgumentTypes ();
164171 mi .signature = getMethodSignature (root , m .getReturnType (),
165- params );
172+ params );
166173
167174 if (mi .signature != null ) {
168175 if (isStatic ) {
@@ -195,7 +202,7 @@ private static void setFieldInfo(ClassDescriptor clazz, TreeNode node, TreeNode
195202 TypeDescriptor t = f .getType ();
196203 boolean isPrimitive = ClassUtil .isPrimitive (t );
197204
198- fi .valueType = isPrimitive ? TreeNode .getPrimitive (t ): getOrCreateNode (root , t );
205+ fi .valueType = isPrimitive ? TreeNode .getPrimitive (t ) : getOrCreateNode (root , t );
199206 fi .isFinalType = f .isFinal ();
200207
201208 if (f .isStatic ()) {
@@ -242,8 +249,38 @@ private static void getFieldsFromImplementedInterfaces(ClassDescriptor clazz, Tr
242249 }
243250 }
244251
252+ private static MethodDescriptor [] getDefaultMethodsFromImplementedInterfaces (ClassDescriptor clazz , MethodDescriptor [] originalClassMethodDescriptors ) {
253+ HashSet <MethodDescriptor > defaultMethods = getAllDefaultMethodsFromImplementedInterfaces (clazz );
254+ HashSet <MethodDescriptor > classMethods = new HashSet <MethodDescriptor >(Arrays .asList (originalClassMethodDescriptors ));
255+ defaultMethods .removeAll (classMethods );
256+
257+ return defaultMethods .toArray (new MethodDescriptor [0 ]);
258+ }
259+
260+ private static HashSet <MethodDescriptor > getAllDefaultMethodsFromImplementedInterfaces (ClassDescriptor clazz ) {
261+ return getAllDefaultMethodsFromImplementedInterfacesRecursively (clazz , new HashSet <MethodDescriptor >());
262+ }
263+
264+ private static HashSet <MethodDescriptor > getAllDefaultMethodsFromImplementedInterfacesRecursively (ClassDescriptor clazz , HashSet <MethodDescriptor > collectedDefaultMethods ) {
265+ String [] implementedInterfacesNames = clazz .getInterfaceNames ();
266+
267+ for (String implementedInterfaceName : implementedInterfacesNames ) {
268+ ClassDescriptor interfaceClass = ClassRepo .findClass (implementedInterfaceName );
269+
270+ for (MethodDescriptor md : interfaceClass .getMethods ()) {
271+ if (!md .isStatic () && !md .isAbstract ()) {
272+ collectedDefaultMethods .add (md );
273+ }
274+ }
275+
276+ collectedDefaultMethods .addAll (getAllDefaultMethodsFromImplementedInterfacesRecursively (interfaceClass , new HashSet <MethodDescriptor >()));
277+ }
278+
279+ return collectedDefaultMethods ;
280+ }
281+
245282 private static TreeNode getOrCreateNode (TreeNode root , TypeDescriptor type )
246- throws Exception {
283+ throws Exception {
247284 TreeNode node ;
248285
249286 String typeName = type .getSignature ();
@@ -272,7 +309,7 @@ private static TreeNode getOrCreateNode(TreeNode root, ClassDescriptor clazz, St
272309
273310 if (ClassUtil .isArray (clazz )) {
274311 throw new UnsupportedOperationException ("unexpected class="
275- + clazz .getClassName ());
312+ + clazz .getClassName ());
276313 }
277314
278315 TreeNode node = root ;
@@ -307,7 +344,7 @@ private static TreeNode getOrCreateNode(TreeNode root, ClassDescriptor clazz, St
307344 if (child == null ) {
308345 child = node .createChild (outerClassname );
309346 child .nodeType = outer .isInterface () ? TreeNode .Interface
310- : TreeNode .Class ;
347+ : TreeNode .Class ;
311348 if (outer .isStatic ()) {
312349 child .nodeType |= TreeNode .Static ;
313350 }
@@ -324,7 +361,7 @@ private static TreeNode getOrCreateNode(TreeNode root, ClassDescriptor clazz, St
324361 child .nodeType = tmp .nodeType ;
325362 } else {
326363 child .nodeType = clazz .isInterface () ? TreeNode .Interface
327- : TreeNode .Class ;
364+ : TreeNode .Class ;
328365 if (clazz .isStatic ()) {
329366 child .nodeType |= TreeNode .Static ;
330367 }
@@ -337,8 +374,8 @@ private static TreeNode getOrCreateNode(TreeNode root, ClassDescriptor clazz, St
337374 baseClass = ClassUtil .getClassByName (predefinedSuperClassname );
338375 } else {
339376 baseClass = clazz .isInterface ()
340- ? ClassUtil .getClassByName ("java.lang.Object" )
341- : ClassUtil .getSuperclass (clazz );
377+ ? ClassUtil .getClassByName ("java.lang.Object" )
378+ : ClassUtil .getSuperclass (clazz );
342379 }
343380 if (baseClass != null ) {
344381 node .baseClassNode = getOrCreateNode (root , baseClass , null );
@@ -358,7 +395,7 @@ private static void copyBasePublicApi(ClassDescriptor baseClass, TreeNode node,
358395 }
359396
360397 private static TreeNode createArrayNode (TreeNode root , String className )
361- throws Exception {
398+ throws Exception {
362399 TreeNode currentNode = root ;
363400 String currentClassname = className ;
364401
@@ -385,7 +422,7 @@ private static TreeNode createArrayNode(TreeNode root, String className)
385422 } else {
386423 ClassDescriptor clazz = ClassRepo .findClass (name );
387424 child .nodeType = clazz .isInterface () ? TreeNode .Interface
388- : TreeNode .Class ;
425+ : TreeNode .Class ;
389426 if (clazz .isStatic ()) {
390427 child .nodeType |= TreeNode .Static ;
391428 }
@@ -397,22 +434,22 @@ private static TreeNode createArrayNode(TreeNode root, String className)
397434 }
398435
399436 private static ArrayList <TreeNode > getMethodSignature (TreeNode root ,
400- TypeDescriptor retType , TypeDescriptor [] params ) throws Exception {
437+ TypeDescriptor retType , TypeDescriptor [] params ) throws Exception {
401438 ArrayList <TreeNode > sig = new ArrayList <TreeNode >();
402439 boolean isVoid = retType .equals (TypeDescriptor .VOID );
403440
404441 TreeNode node = null ;
405442 if (!isVoid ) {
406443 boolean isPrimitive = ClassUtil .isPrimitive (retType );
407444 node = isPrimitive ? TreeNode .getPrimitive (retType )
408- : getOrCreateNode (root , retType );
445+ : getOrCreateNode (root , retType );
409446 }
410447 sig .add (node );
411448
412449 for (TypeDescriptor param : params ) {
413450 boolean isPrimitive = ClassUtil .isPrimitive (param );
414451 node = isPrimitive ? TreeNode .getPrimitive (param )
415- : getOrCreateNode (root , param );
452+ : getOrCreateNode (root , param );
416453 if (node == null ) {
417454 return null ;
418455 }
@@ -421,4 +458,16 @@ private static ArrayList<TreeNode> getMethodSignature(TreeNode root,
421458
422459 return sig ;
423460 }
461+
462+ private static <T > T [] concatenate (T [] a , T [] b ) {
463+ int aLen = a .length ;
464+ int bLen = b .length ;
465+
466+ @ SuppressWarnings ("unchecked" )
467+ T [] c = (T []) Array .newInstance (a .getClass ().getComponentType (), aLen + bLen );
468+ System .arraycopy (a , 0 , c , 0 , aLen );
469+ System .arraycopy (b , 0 , c , aLen , bLen );
470+
471+ return c ;
472+ }
424473}
0 commit comments