1   package org.apache.bcel.classfile;
2   
3   /* ====================================================================
4    * The Apache Software License, Version 1.1
5    *
6    * Copyright (c) 2001 The Apache Software Foundation.  All rights
7    * reserved.
8    *
9    * Redistribution and use in source and binary forms, with or without
10   * modification, are permitted provided that the following conditions
11   * are met:
12   *
13   * 1. Redistributions of source code must retain the above copyright
14   *    notice, this list of conditions and the following disclaimer.
15   *
16   * 2. Redistributions in binary form must reproduce the above copyright
17   *    notice, this list of conditions and the following disclaimer in
18   *    the documentation and/or other materials provided with the
19   *    distribution.
20   *
21   * 3. The end-user documentation included with the redistribution,
22   *    if any, must include the following acknowledgment:
23   *       "This product includes software developed by the
24   *        Apache Software Foundation (http://www.apache.org/)."
25   *    Alternately, this acknowledgment may appear in the software itself,
26   *    if and wherever such third-party acknowledgments normally appear.
27   *
28   * 4. The names "Apache" and "Apache Software Foundation" and
29   *    "Apache BCEL" must not be used to endorse or promote products
30   *    derived from this software without prior written permission. For
31   *    written permission, please contact apache@apache.org.
32   *
33   * 5. Products derived from this software may not be called "Apache",
34   *    "Apache BCEL", nor may "Apache" appear in their name, without
35   *    prior written permission of the Apache Software Foundation.
36   *
37   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
38   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
39   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
40   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
41   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
42   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
43   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
44   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
45   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
46   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
47   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
48   * SUCH DAMAGE.
49   * ====================================================================
50   *
51   * This software consists of voluntary contributions made by many
52   * individuals on behalf of the Apache Software Foundation.  For more
53   * information on the Apache Software Foundation, please see
54   * <http://www.apache.org/>.
55   */
56  
57  import  org.apache.bcel.Constants;
58  import  org.apache.bcel.util.SyntheticRepository;
59  import  org.apache.bcel.util.ClassVector;
60  import  org.apache.bcel.util.ClassQueue;
61  import  org.apache.bcel.generic.Type;
62  
63  import  java.io.*;
64  import  java.util.StringTokenizer;
65  
66  /***
67   * Represents a Java class, i.e., the data structures, constant pool,
68   * fields, methods and commands contained in a Java .class file.
69   * See <a href="ftp://java.sun.com/docs/specs/">JVM 
70   * specification</a> for details.
71  
72   * The intent of this class is to represent a parsed or otherwise existing
73   * class file.  Those interested in programatically generating classes
74   * should see the <a href="../generic/ClassGen.html">ClassGen</a> class.
75  
76   * @version $Id: JavaClass.java,v 1.13 2002/07/11 19:39:04 mdahm Exp $
77   * @see org.apache.bcel.generic.ClassGen
78   * @author  <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A>
79   */
80  public class JavaClass extends AccessFlags implements Cloneable, Node {
81    private String       file_name;
82    privateb> String       package_name;
83    private String       source_file_name = "<Unknown>";
84    private int          class_name_index;
85    private int          superclass_name_index;
86    private String       class_name;
87    private String       superclass_name;
88    private int          major, minor;  // Compiler version
89    private ConstantPool constant_pool; // Constant pool
90    private int[]        interfaces;    // implemented interfaces
91    private String[]     interface_names;
92    private Field[]      fields;        // Fields, i.e., variables of class
93    private Method[]     methods;       // methods defined in the class
94    private Attribute[]  attributes;    // attributes defined in the class
95    private byte         source = HEAP; // Generated in memory
96  
97    public static final byte HEAP = 1;
98    public static final byte FILE = 2;
99    public static final byte ZIP  = 3;
100 
101   static boolean debug = false; // Debugging on/off
102   static char    sep   = '/';   // directory separator
103 
104   /***
105    * In cases where we go ahead and create something,
106    * use the default SyntheticRepository, because we
107    * don't know any better.
108    */
109   private transient org.apache.bcel.util.Repository repository = 
110     SyntheticRepository.getInstance();
111 
112   /***
113    * Constructor gets all contents as arguments.
114    *
115    * @param class_name_index Index into constant pool referencing a
116    * ConstantClass that represents this class.
117    * @param superclass_name_index Index into constant pool referencing a
118    * ConstantClass that represents this class's superclass.
119    * @param file_name File name
120    * @param major Major compiler version
121    * @param minor Minor compiler version
122    * @param access_flags Access rights defined by bit flags
123    * @param constant_pool Array of constants
124    * @param interfaces Implemented interfaces
125    * @param fields Class fields
126    * @param methods Class methods
127    * @param attributes Class attributes
128    * @param source Read from file or generated in memory?
129    */
130   public JavaClass(int        class_name_index,
131 		   int        superclass_name_index,
132 		   String     file_name,
133 		   int        major,
134 		   int        minor,
135 		   int        access_flags,
136 		   ConstantPool constant_pool,
137 		   int[]      interfaces,
138 		   Field[]      fields,
139 		   Method[]     methods,
140 		   Attribute[]  attributes,
141 		   byte          source)
142   {
143     if(interfaces == null) // Allowed for backward compatibility
144       interfaces = new int[0];
145     if(attributes == null)
146       this.attributes = new Attribute[0];
147     if(fields == null)
148       fields = new Field[0];
149     if(methods == null)
150       methods = new Method[0];
151 
152     this.class_name_index      = class_name_index;
153     this.superclass_name_index = superclass_name_index;
154     this.file_name             = file_name;
155     this.major                 = major;
156     this.minor                 = minor;
157     this.access_flags          = access_flags;
158     this.constant_pool         = constant_pool;
159     this.interfaces            = interfaces;
160     this.fields                = fields;
161     this.methods               = methods;
162     this.attributes            = attributes;
163     this.source                = source;
164 
165     // Get source file name if available
166     for(int i=0; i < attributes.length; i++) {
167       if(attributes[i] instanceof SourceFile) {
168 	source_file_name = ((SourceFile)attributes[i]).getSourceFileName();
169 	break;
170       }
171     }
172 
173     /* According to the specification the following entries must be of type
174      * `ConstantClass' but we check that anyway via the 
175      * `ConstPool.getConstant' method.
176      */
177     class_name = constant_pool.getConstantString(class_name_index, 
178 						 Constants.CONSTANT_Class);
179     class_name = Utility.compactClassName(class_name, false);
180 
181     int index = class_name.lastIndexOf('.');
182     if(index < 0)
183       package_name =/package-summary.html">>_name = "";
184     else
185       package_name = class_name/substring(0, index)/package-summary.html">>_name = class_name.substring(0, index);
186 
187     if(superclass_name_index > 0) { // May be zero -> class is java.lang.Object
188       superclass_name = constant_pool.getConstantString(superclass_name_index,
189 							Constants.CONSTANT_Class);
190       superclass_name = Utility.compactClassName(superclass_name, false);
191     }
192     else
193       superclass_name = "java.lang.Object";    
194 
195     interface_names = new String[interfaces.length];
196     for(int i=0; i < interfaces.length; i++) {
197       String str = constant_pool.getConstantString(interfaces[i], Constants.CONSTANT_Class);
198       interface_names[i] = Utility.compactClassName(str, false);
199     }
200   }
201 
202   /***
203    * Constructor gets all contents as arguments.
204    *
205    * @param class_name_index Class name
206    * @param superclass_name_index Superclass name
207    * @param file_name File name
208    * @param major Major compiler version
209    * @param minor Minor compiler version
210    * @param access_flags Access rights defined by bit flags
211    * @param constant_pool Array of constants
212    * @param interfaces Implemented interfaces
213    * @param fields Class fields
214    * @param methods Class methods
215    * @param attributes Class attributes
216    */
217   public JavaClass(int        class_name_index,
218 		   int        superclass_name_index,
219 		   String     file_name,
220 		   int        major,
221 		   int        minor,
222 		   int        access_flags,
223 		   ConstantPool constant_pool,
224 		   int[]      interfaces,
225 		   Field[]      fields,
226 		   Method[]     methods,
227 		   Attribute[]  attributes) {
228     this(class_name_index, superclass_name_index, file_name, major, minor, access_flags,
229 	 constant_pool, interfaces, fields, methods, attributes, HEAP);
230   }
231 
232       
233   /***
234    * Called by objects that are traversing the nodes of the tree implicitely
235    * defined by the contents of a Java class. I.e., the hierarchy of methods,
236    * fields, attributes, etc. spawns a tree of objects.
237    *
238    * @param v Visitor object
239    */
240   public void accept(Visitor v) {
241     v.visitJavaClass(this);
242   }
243 
244   /* Print debug information depending on `JavaClass.debug'
245    */
246   static final void Debug(String str) {
247     if(debug)
248       System.out.println(str);
249   }
250 
251   /*** 
252    * Dump class to a file.
253    *
254    * @param file Output file
255    * @throws IOException
256    */
257   public void dump(File file) throws IOException
258   {
259     String parent = file.getParent();
260 
261     if(parent != null) {
262       File dir = new File(parent);
263       
264       if(dir != null)
265 	dir.mkdirs();
266     }
267 
268     dump(new DataOutputStream(new FileOutputStream(file)));
269   }
270 
271   /*** 
272    * Dump class to a file named file_name.
273    *
274    * @param file_name Output file name
275    * @exception IOException
276    */
277   public void dump(String file_name) throws IOException
278   {
279     dump(new File(file_name));
280   }
281 
282   /***
283    * @return class in binary format
284    */
285   public byte[] getBytes() {
286     ByteArrayOutputStream s  = new ByteArrayOutputStream();
287     DataOutputStream      ds = new DataOutputStream(s);
288 
289     try {
290       dump(ds);
291     } catch(IOException e) {
292       e.printStackTrace();
293     } finally {
294       try { ds.close(); } catch(IOException e2) { e2.printStackTrace(); }
295     }
296 
297     return s.toByteArray();
298   }
299 
300   /***
301    * Dump Java class to output stream in binary format.
302    *
303    * @param file Output stream
304    * @exception IOException
305    */
306   public void dump(OutputStream file) throws IOException {
307     dump(new DataOutputStream(file));
308   }
309 
310   /***
311    * Dump Java class to output stream in binary format.
312    *
313    * @param file Output stream
314    * @exception IOException
315    */
316   public void dump(DataOutputStream file) throws IOException
317   {
318     file.writeInt(0xcafebabe);
319     file.writeShort(minor);
320     file.writeShort(major);
321 
322     constant_pool.dump(file);
323 	
324     file.writeShort(access_flags);
325     file.writeShort(class_name_index);
326     file.writeShort(superclass_name_index);
327 
328     file.writeShort(interfaces.length);
329     for(int i=0; i < interfaces.length; i++)
330       file.writeShort(interfaces[i]);
331 
332     file.writeShort(fields.length);
333     for(int i=0; i < fields.length; i++)
334       fields[i].dump(file);
335 
336     file.writeShort(methods.length);
337     for(int i=0; i < methods.length; i++)
338       methods[i].dump(file);
339 
340     if(attributes != null) {
341       file.writeShort(attributes.length);
342       for(int i=0; i < attributes.length; i++)
343 	attributes[i].dump(file);
344     }
345     else
346       file.writeShort(0);
347 
348     file.close();
349   }
350 
351   /***
352    * @return Attributes of the class.
353    */
354   public Attribute[] getAttributes() { return attributes; }
355 
356   /***
357    * @return Class name.
358    */
359   public String getClassName()       { return class_name; }
360 
361   /***
362    * @return Package name.
363    */
364   public String getPackageName()       { return package_name; }    
365 
366   /***
367    * @return Class name index.
368    */
369   public int getClassNameIndex()   { return class_name_index; }
370 
371   /***
372    * @return Constant pool.
373    */
374   public ConstantPool getConstantPool() { return constant_pool; }
375 
376   /***
377    * @return Fields, i.e., variables of the class. Like the JVM spec
378    * mandates for the classfile format, these fields are those specific to
379    * this class, and not those of the superclass or superinterfaces.
380    */
381   public Field[] getFields()         { return fields; }    
382 
383   /***
384    * @return File name of class, aka SourceFile attribute value
385    */
386   public String getFileName()        { return file_name; }    
387 
388   /***
389    * @return Names of implemented interfaces.
390    */
391   public String[] getInterfaceNames()  { return interface_names; }    
392 
393   /***
394    * @return Indices in constant pool of implemented interfaces.
395    */
396   public int[] getInterfaceIndices()     { return interfaces; }    
397 
398   /***
399    * @return Major number of class file version.
400    */
401   public int  getMajor()           { return major; }    
402 
403   /***
404    * @return Methods of the class.
405    */
406   public Method[] getMethods()       { return methods; }    
407 
408   /***
409    * @return A org.apache.bcel.classfile.Method corresponding to
410    * java.lang.reflect.Method if any
411    */
412   public Method getMethod(java.lang.reflect.Method m) {
413     for(int i = 0; i < methods.length; i++) {
414       Method method = methods[i];
415 
416       if(m.getName().equals(method.getName()) &&
417 	 (m.getModifiers() == method.getModifiers()) &&
418 	 Type.getSignature(m).equals(method.getSignature())) {
419 	return method;
420       }
421     }
422 
423     return null;
424   }
425 
426   /***
427    * @return Minor number of class file version.
428    */
429   public int  getMinor()           { return minor; }    
430 
431   /***
432    * @return sbsolute path to file where this class was read from
433    */
434   public String getSourceFileName()  { return source_file_name; }    
435 
436   /***
437    * @return Superclass name.
438    */
439   public String getSuperclassName()  { return superclass_name; }    
440 
441   /***
442    * @return Class name index.
443    */
444   public int getSuperclassNameIndex() { return superclass_name_index; }    
445 
446   static {
447     // Debugging ... on/off
448     String debug = System.getProperty("JavaClass.debug");
449 
450     if(debug != null)
451       JavaClass.debug = new Boolean(debug).booleanValue();
452 
453     // Get path separator either / or \ usually
454     String sep = System.getProperty("file.separator");
455 
456     if(sep != null)
457       try {
458 	JavaClass.sep = sep.charAt(0);
459       } catch(StringIndexOutOfBoundsException e) {} // Never reached
460   }
461 
462   /***
463    * @param attributes .
464    */
465   public void setAttributes(Attribute[] attributes) {
466     this.attributes = attributes;
467   }    
468 
469   /***
470    * @param class_name .
471    */
472   public void setClassName(String class_name) {
473     this.class_name = class_name;
474   }    
475 
476   /***
477    * @param class_name_index .
478    */
479   public void setClassNameIndex(int class_name_index) {
480     this.class_name_index = class_name_index;
481   }    
482 
483   /***
484    * @param constant_pool .
485    */
486   public void setConstantPool(ConstantPool constant_pool) {
487     this.constant_pool = constant_pool;
488   }    
489 
490   /***
491    * @param fields .
492    */
493   public void setFields(Field[] fields) {
494     this.fields = fields;
495   }    
496 
497   /***
498    * Set File name of class, aka SourceFile attribute value
499    */
500   public void setFileName(String file_name) {
501     this.file_name = file_name;
502   }    
503 
504   /***
505    * @param interface_names .
506    */
507   public void setInterfaceNames(String[] interface_names) {
508     this.interface_names = interface_names;
509   }    
510 
511   /***
512    * @param interfaces .
513    */
514   public void setInterfaces(int[] interfaces) {
515     this.interfaces = interfaces;
516   }    
517 
518   /***
519    * @param major .
520    */
521   public void setMajor(int major) {
522     this.major = major;
523   }    
524 
525   /***
526    * @param methods .
527    */
528   public void setMethods(Method[] methods) {
529     this.methods = methods;
530   }    
531 
532   /***
533    * @param minor .
534    */
535   public void setMinor(int minor) {
536     this.minor = minor;
537   }    
538 
539   /***
540    * Set absolute path to file this class was read from.
541    */
542   public void setSourceFileName(String source_file_name) {
543     this.source_file_name = source_file_name;
544   }    
545 
546   /***
547    * @param superclass_name .
548    */
549   public void setSuperclassName(String superclass_name) {
550     this.superclass_name = superclass_name;
551   }    
552 
553   /***
554    * @param superclass_name_index .
555    */
556   public void setSuperclassNameIndex(int superclass_name_index) {
557     this.superclass_name_index = superclass_name_index;
558   }    
559 
560   /***
561    * @return String representing class contents.
562    */
563   public String toString() {
564     String access = Utility.accessToString(access_flags, true);
565     access = access.equals("")? "" : (access + " ");
566 
567     StringBuffer buf = new StringBuffer(access +
568 					Utility.classOrInterface(access_flags) + 
569 					" " +
570 					class_name + " extends " +
571 					Utility.compactClassName(superclass_name,
572 								 false) + '\n');
573     int size = interfaces.length;
574 
575     if(size > 0) {
576       buf.append("implements\t\t");
577 
578       for(int i=0; i < size; i++) {
579 	buf.append(interface_names[i]);
580 	if(i < size - 1)
581 	  buf.append(", ");
582       }
583 
584       buf.append('\n');
585     }
586 
587     buf.append("filename\t\t" + file_name + '\n');
588     buf.append("compiled from\t\t" + source_file_name + '\n');
589     buf.append("compiler version\t" + major + "." + minor + '\n');
590     buf.append("access flags\t\t" + access_flags + '\n');
591     buf.append("constant pool\t\t" + constant_pool.getLength() + " entries\n");
592     buf.append("ACC_SUPER flag\t\t" + isSuper() + "\n");
593 
594     if(attributes.length > 0) {
595       buf.append("\nAttribute(s):\n");
596       for(int i=0; i < attributes.length; i++)
597 	buf.append(indent(attributes[i]));
598     }
599 
600     if(fields.length > 0) {
601       buf.append("\n" + fields.length + " fields:\n");
602       for(int i=0; i < fields.length; i++)
603 	buf.append("\t" + fields[i] + '\n');
604     }
605 
606     if(methods.length > 0) {
607       buf.append("\n" + methods.length + " methods:\n");
608       for(int i=0; i < methods.length; i++)
609 	buf.append("\t" + methods[i] + '\n');
610     }
611 
612     return buf.toString();
613   }    
614 
615   private static final String indent(Object obj) {
616     StringTokenizer tok = new StringTokenizer(obj.toString(), "\n");
617     StringBuffer buf = new StringBuffer();
618 
619     while(tok.hasMoreTokens())
620       buf.append("\t" + tok.nextToken() + "\n");
621 
622     return buf.toString();
623   }
624 
625   /***
626    * @return deep copy of this class
627    */
628   public JavaClass copy() {
629     JavaClass c = null;
630 
631     try {
632       c = (JavaClass)clone();
633     } catch(CloneNotSupportedException e) {}
634 
635     c.constant_pool   = constant_pool.copy();
636     c.interfaces      = (int[])interfaces.clone();
637     c.interface_names = (String[])interface_names.clone();
638 
639     c.fields = new Field[fields.length];
640     for(int i=0; i < fields.length; i++)
641       c.fields[i] = fields[i].copy(c.constant_pool);
642 
643     c.methods = new Method[methods.length];
644     for(int i=0; i < methods.length; i++)
645       c.methods[i] = methods[i].copy(c.constant_pool);
646 
647     c.attributes = new Attribute[attributes.length];
648     for(int i=0; i < attributes.length; i++)
649       c.attributes[i] = attributes[i].copy(c.constant_pool);
650 
651     return c;
652   }
653 
654   public final boolean isSuper() {
655     return (access_flags & Constants.ACC_SUPER) != 0;
656   }
657 
658   public final boolean isClass() {
659     return (access_flags & Constants.ACC_INTERFACE) == 0;
660   }
661 
662   /*** @return returns either HEAP (generated), FILE, or ZIP
663    */
664   public final byte getSource() {
665     return source;
666   }
667 
668   /********************** New repository functionality *********************/
669 
670   /***
671    * Gets the ClassRepository which holds its definition. By default
672    * this is the same as SyntheticRepository.getInstance();
673    */
674   public org.apache.bcel.util.Repository getRepository() {
675     return repository;
676   }
677 
678   /***
679    * Sets the ClassRepository which loaded the JavaClass.
680    * Should be called immediately after parsing is done.
681    */
682   public void setRepository(org.apache.bcel.util.Repository repository) {
683     this.repository = repository;
684   }
685 
686   /*** Equivalent to runtime "instanceof" operator.
687    *
688    * @return true if this JavaClass is derived from teh super class
689    */
690   public final boolean instanceOf(JavaClass super_class) {
691     if(this.equals(super_class))
692       return true;
693 
694     JavaClass[] super_classes = getSuperClasses();
695 
696     for(int i=0; i < super_classes.length; i++) {
697       if(super_classes[i].equals(super_class)) {
698 	return true;
699       }
700     }
701 
702     if(super_class.isInterface()) {
703       return implementationOf(super_class);
704     }
705 
706     return false;
707   }
708 
709   /***
710    * @return true, if clazz is an implementation of interface inter
711    */
712   public boolean implementationOf(JavaClass inter) {
713     if(!inter.isInterface()) {
714       throw new IllegalArgumentException(inter.getClassName() + " is no interface");
715     }
716 
717     if(this.equals(inter)) {
718       return true;
719     }
720 
721     JavaClass[] super_interfaces = getAllInterfaces();
722 
723     for(int i=0; i < super_interfaces.length; i++) {
724       if(super_interfaces[i].equals(inter)) {
725 	return true;
726       }
727     }
728 
729     return false;
730   }
731 
732   /***
733    * @return the superclass for this JavaClass object, or null if this
734    * is java.lang.Object
735    */
736   public JavaClass getSuperClass() {
737     if("java.lang.Object".equals(getClassName())) {
738       return null;
739     }
740 
741     try {
742       return repository.loadClass(getSuperclassName());
743     } catch(ClassNotFoundException e) {
744       System.err.println(e);
745       return null;
746     }
747   }
748 
749   /***
750    * @return list of super classes of this class in ascending order, i.e.,
751    * java.lang.Object is always the last element
752    */
753   public JavaClass[] getSuperClasses() {
754     JavaClass   clazz = this;
755     ClassVector vec   = new ClassVector();
756 
757     for(clazz = clazz.getSuperClass(); clazz != null;
758 	clazz = clazz.getSuperClass())
759     {
760       vec.addElement(clazz);
761     }
762 
763     return vec.toArray();
764   }
765 
766   /***
767    * Get interfaces directly implemented by this JavaClass.
768    */
769   public JavaClass[] getInterfaces() {
770     String[]    interfaces = getInterfaceNames();
771     JavaClass[] classes    = new JavaClass[interfaces.length];
772 
773     try {
774       for(int i = 0; i < interfaces.length; i++) {
775 	classes[i] = repository.loadClass(interfaces[i]);
776       }
777     } catch(ClassNotFoundException e) {
778       System.err.println(e);
779       return null;
780     }
781 
782     return classes;
783   }
784 
785   /***
786    * Get all interfaces implemented by this JavaClass (transitively).
787    */
788   public JavaClass[] getAllInterfaces() {
789     ClassQueue  queue = new ClassQueue();
790     ClassVector vec   = new ClassVector();
791     
792     queue.enqueue(this);
793     
794     while(!queue.empty()) {
795       JavaClass clazz = queue.dequeue();
796       
797       JavaClass   souper     = clazz.getSuperClass();
798       JavaClass[] interfaces = clazz.getInterfaces();
799       
800       if(clazz.isInterface()) {
801 	vec.addElement(clazz);
802       } else {
803 	if(souper != null) {
804 	  queue.enqueue(souper);
805 	}
806       }
807       
808       for(int i = 0; i < interfaces.length; i++) {
809 	queue.enqueue(interfaces[i]);
810       }
811     }
812 	    
813     return vec.toArray();
814   }
815 }
This page was automatically generated by Maven