Clover Coverage Report - SmartWeb
Coverage timestamp: Sun Jun 8 2008 21:20:12 CEST
../../../img/srcFileCovDistChart0.png 29% of files have more coverage
205   717   111   5,86
100   430   0,54   17,5
35     3,17  
2    
7,1% of code in this file is excluded from these metrics.
 
  BusinessObjectFactory       Line # 57 138 75 0% 0.0
  BusinessObjectFactory.Paginator       Line # 458 67 36 0% 0.0
 
No Tests
 
1    /*
2    * The SmartWeb Framework
3    * Copyright (C) 2004-2006
4    *
5    * This library is free software; you can redistribute it and/or
6    * modify it under the terms of the GNU Lesser General Public
7    * License as published by the Free Software Foundation; either
8    * version 2.1 of the License, or (at your option) any later version.
9    *
10    * This library is distributed in the hope that it will be useful,
11    * but WITHOUT ANY WARRANTY; without even the implied warranty of
12    * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13    * Lesser General Public License for more details.
14    *
15    * You should have received a copy of the GNU Lesser General Public
16    * License along with this library; if not, write to the Free Software
17    * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18    *
19    * For further informations on the SmartWeb Framework please visit
20    *
21    * http://smartweb.sourceforge.net
22    */
23    package net.smartlab.web;
24   
25    import java.io.Serializable;
26    import java.util.ArrayList;
27    import java.util.Collection;
28    import java.util.HashMap;
29    import java.util.Iterator;
30    import java.util.List;
31    import java.util.Map;
32    import net.smartlab.web.DataAccessObject.SearchInfo.Filter;
33    import net.smartlab.web.config.FactoryConfigurationStrategy;
34    import net.smartlab.web.config.JNDIConfigurationStrategy;
35    import org.apache.commons.logging.Log;
36    import org.apache.commons.logging.LogFactory;
37    import org.hibernate.Criteria;
38    import org.hibernate.HibernateException;
39    import org.hibernate.Query;
40    import org.hibernate.Session;
41    import org.hibernate.SessionFactory;
42    import org.hibernate.Transaction;
43    import org.hibernate.criterion.Expression;
44    import org.hibernate.criterion.Order;
45    import org.hibernate.criterion.Projections;
46    import org.hibernate.impl.CriteriaImpl;
47    import org.hibernate.transform.ResultTransformer;
48   
49    /**
50    * This class provides basic template for an Hibernate based implementation of
51    * the DAO pattern.
52    *
53    * @author rlogiacco,gperrone
54    * @uml.dependency supplier="net.smartlab.web.DataTransferObject"
55    * @uml.dependency supplier="net.smartlab.web.config.FactoryConfigurationStrategy"
56    */
 
57    public abstract class BusinessObjectFactory implements DataAccessObject {
58   
59    /**
60    * Provides logging capabilities to the factory.
61    */
62    protected final Log logger = LogFactory.getLog(this.getClass());
63   
64    /**
65    * Stores the Hibernate Session instance available for this request.
66    */
67    private static final ThreadLocal session = new ThreadLocal();
68   
69    /**
70    * Stores the Hibernate Transaction instance available for this request.
71    */
72    private static final ThreadLocal transaction = new ThreadLocal();
73   
74    /**
75    * Caches a reference to the Hibernate Session Factory to avoid further
76    * lookups.
77    */
78    protected SessionFactory factory;
79   
80    /**
81    * Strategy to retrieve the configuration file.
82    */
83    private static FactoryConfigurationStrategy strategy = new JNDIConfigurationStrategy();
 
84  0 toggle static {
85  0 try {
86  0 String strategy = System.getProperty("smartweb.factory.strategy");
87  0 if (strategy != null) {
88  0 BusinessObjectFactory.strategy = (FactoryConfigurationStrategy)Class.forName(strategy).newInstance();
89    } else {
90  0 LogFactory.getLog(BusinessObjectFactory.class).warn(
91    "No configuration found: falling back to default configuration");
92    }
93    } catch (Exception e) {
94    LogFactory.getLog(BusinessObjectFactory.class).fatal("Error configuring SmartWeb", e);
95    }
96    }
97   
98   
99    /**
100    * Changes the strategy used to configure the framework.
101    *
102    * @param strategy an implementation of the
103    * <code>FactoryConfigurationStrategy</code> interface.
104    */
 
105  0 toggle public static void setConfigurationStrategy(FactoryConfigurationStrategy strategy) {
106  0 BusinessObjectFactory.strategy = strategy;
107    }
108   
109    /**
110    * Closes the connection to the persistence tier.
111    *
112    * @throws DAOException if the persistence tier generates any error while
113    * performing the resource release.
114    */
 
115  0 toggle public static void close() throws DAOException {
116  0 Map sessionMap = (Map) BusinessObjectFactory.session.get();
117  0 if (sessionMap != null) {
118  0 Iterator iter = sessionMap.keySet().iterator();
119  0 while (iter.hasNext()) {
120  0 Session session = (Session) sessionMap.get(iter.next());
121  0 if (session != null) {
122  0 try {
123  0 session.flush();
124  0 session.close();
125    } catch (HibernateException he) {
126    throw new DAOException("errors.session.close", he);
127    } finally {
128  0 BusinessObjectFactory.session.set(null);
129    }
130    }
131    }
132    }
133    }
134   
135    /**
136    * Protected default constructor to allow subclassing. Provides the startup
137    * initialization and the Hibernate Session Factory lookup. The Hibernate
138    * configuration file used must reside into the <code>META-INF</code>
139    * directory of the topmost packaging archive and should be named
140    * <code>smartweb.jar.hcf</code> or have the name of the JAR file
141    * containing the subclass followed by the <code>.hcf</code> suffix. TODO
142    * example
143    */
 
144  0 toggle protected BusinessObjectFactory() {
145  0 this.factory = strategy.getSessionFactory(this);
146    }
147   
148    /**
149    * Returns the current Hibernate Session. If a Session was previously
150    * established during the same request the already established instance is
151    * returned otherwise a new instance is retriven from the Session Factory.
152    *
153    * @return the current connection to the persistence layer or a new one if
154    * not previously established.
155    * @throws DAOException if an error occurs trying to establish the
156    * connection.
157    */
 
158  0 toggle protected Session current() throws DAOException {
159  0 if (logger.isDebugEnabled()) {
160  0 logger.debug("current() - start");
161    }
162    // Session session = (Session)BusinessObjectFactory.session.get();
163  0 Session session = null;
164  0 Map sessionMap = (Map) BusinessObjectFactory.session.get();
165  0 if (sessionMap == null) {
166  0 sessionMap = new HashMap();
167    }
168  0 String archive = Domain.getLastArchiveName(this.getClass());
169  0 String configFile = Domain.getResource(this.getClass(), new String[] {"/META-INF/" + archive + ".hcf",
170    "/META-INF/smartweb.jar.hcf"}).getFile();
171  0 session = (Session) sessionMap.get(configFile);
172  0 if (session == null) {
173  0 try {
174  0 session = factory.openSession();
175  0 sessionMap.put(configFile, session);
176  0 BusinessObjectFactory.session.set(sessionMap);
177    } catch (Exception e) {
178    throw new DAOException("errors.session.config", e);
179    }
180    }
181   
182  0 return session;
183    }
184   
185    /**
186    * @see net.smartlab.web.DataAccessObject#findByKey(java.io.Serializable)
187    */
 
188  0 toggle public Object findByKey(Serializable key) throws DAOException {
189  0 if (logger.isDebugEnabled()) {
190  0 logger.debug("findByKey(key = " + key + ") - start");
191    }
192  0 Serializable convertedKey = this.convertKey(key);
193  0 if (convertedKey == null) {
194  0 try {
195  0 return this.getMappedClass().newInstance();
196    } catch (Exception e) {
197    logger.error("findByKey(key = " + key + ") - instantiation failed", e);
198    throw new DAOException("errors.session.select", e);
199    }
200    } else {
201  0 Session session = this.current();
202  0 try {
203  0 return session.get(this.getMappedClass(), convertedKey);
204    } catch (HibernateException he) {
205    logger.warn("findByKey(key = " + key + ") - deserialization failed", he);
206    throw new UndefinedKeyException(key, this.getMappedClass(), he);
207    }
208    }
209    }
210   
211    /**
212    * @see net.smartlab.web.DataAccessObject#remove(java.lang.Object)
213    */
 
214  0 toggle public void remove(Object object) throws DAOException {
215  0 if (logger.isDebugEnabled()) {
216  0 logger.debug("remove(object = " + object + ") - start");
217    }
218  0 try {
219  0 this.current().delete(object);
220    } catch (HibernateException he) {
221    logger.warn("remove(object = " + object + ") - failed", he);
222    throw new DAOException("errors.session.remove", he);
223    }
224    }
225   
226    /**
227    * @see net.smartlab.web.DataAccessObject#update(java.lang.Object)
228    */
 
229  0 toggle public void update(Object object) throws DAOException {
230  0 if (logger.isDebugEnabled()) {
231  0 logger.debug("update(object = " + object + ") - start");
232    }
233  0 try {
234  0 this.current().saveOrUpdate(object);
235    } catch (HibernateException he) {
236    logger.warn("update(object = " + object + ") - failed", he);
237    this.current().clear();
238    throw new DAOException("errors.session.update", he);
239    }
240    }
241   
242    /**
243    * @see net.smartlab.web.DataAccessObject#list(net.smartlab.web.DataAccessObject.SearchInfo)
244    */
 
245  0 toggle public Collection list(SearchInfo info) throws DAOException {
246  0 if (logger.isDebugEnabled()) {
247  0 logger.debug("list(info = " + info + ") - start");
248    }
249  0 Criteria criteria = this.createCriteria(info);
250  0 try {
251  0 return criteria.list();
252    } catch (HibernateException he) {
253    logger.warn("list(info = " + info + ") - failed", he);
254    throw new DAOException("errors.session.search", he);
255    }
256    }
257   
258    /**
259    * TODO documentation
260    *
261    * @param info
262    * @return
263    * @throws DAOException
264    */
 
265  0 toggle public Collection page(SearchInfo info) throws DAOException {
266  0 if (logger.isDebugEnabled()) {
267  0 logger.debug("page(info = " + info + ") - start");
268    }
269  0 Criteria criteria = this.createCriteria(info);
270  0 try {
271  0 return new Paginator(criteria);
272    } catch (HibernateException he) {
273    logger.warn("page(info = " + info + ") - error", he);
274    throw new DAOException("errors.session.paging", he);
275    }
276    }
277   
278    /**
279    * TODO documentation
280    *
281    * @return
282    */
283    public abstract Class getMappedClass();
284   
285    /**
286    * TODO documentation
287    *
288    * @param key
289    * @return
290    */
 
291  0 toggle public Serializable convertKey(Serializable key) {
292  0 if (key != null) {
293  0 if (key instanceof String) {
294  0 if (key.equals("0")) {
295  0 return null;
296    } else {
297  0 return new Long((String)key);
298    }
299  0 } else if (key instanceof Number) {
300  0 if (((Number)key).longValue() == 0) {
301  0 return null;
302    } else {
303  0 return new Long(((Number)key).toString());
304    }
305    }
306    }
307  0 return key;
308    }
309   
310    /**
311    * TODO documentation
312    *
313    * @param info
314    * @return
315    * @throws DAOException
316    */
 
317  0 toggle public Criteria createCriteria(SearchInfo info) throws DAOException {
318  0 if (logger.isDebugEnabled()) {
319  0 logger.debug("createCriteria(info = " + info + ") - start");
320    }
321  0 Session session = this.current();
322  0 Criteria criteria = session.createCriteria(this.getMappedClass());
323  0 if (info.isUnion()) {
324    // TODO the filters are in OR
325    }
326  0 Iterator filters = info.getFilters().iterator();
327  0 while (filters.hasNext()) {
328  0 if (logger.isTraceEnabled()) {
329  0 logger.trace("createCriteria(info = " + info + ") - parsing filter `" + filters + "`");
330    }
331  0 Filter filter = (Filter)filters.next();
332  0 switch (filter.getCondition()) {
333  0 case SearchInfo.EQUALS:
334  0 for (int i = 0; i < filter.getValues().length; i++) {
335  0 criteria.add(Expression.eq(filter.getColumn(), filter.getValue(i)));
336    }
337  0 break;
338  0 case SearchInfo.GREATER:
339  0 for (int i = 0; i < filter.getValues().length; i++) {
340  0 criteria.add(Expression.gt(filter.getColumn(), filter.getValue(i)));
341    }
342  0 break;
343  0 case SearchInfo.GREATER_EQUALS:
344  0 for (int i = 0; i < filter.getValues().length; i++) {
345  0 criteria.add(Expression.ge(filter.getColumn(), filter.getValue(i)));
346    }
347  0 break;
348  0 case SearchInfo.LESSER:
349  0 for (int i = 0; i < filter.getValues().length; i++) {
350  0 criteria.add(Expression.le(filter.getColumn(), filter.getValue(i)));
351    }
352  0 break;
353  0 case SearchInfo.LESSER_EQUALS:
354  0 for (int i = 0; i < filter.getValues().length; i++) {
355  0 criteria.add(Expression.ge(filter.getColumn(), filter.getValue(i)));
356    }
357  0 break;
358  0 case SearchInfo.NOT_EQUALS:
359  0 for (int i = 0; i < filter.getValues().length; i++) {
360  0 criteria.add(Expression.not(Expression.eq(filter.getColumn(), filter.getValue(i))));
361    }
362  0 break;
363  0 case SearchInfo.BETWEEN:
364  0 criteria.add(Expression.between(filter.getColumn(), filter.getValue(0), filter.getValue(1)));
365  0 break;
366  0 case SearchInfo.LIKE:
367  0 for (int i = 0; i < filter.getValues().length; i++) {
368  0 criteria.add(Expression.like(filter.getColumn(), filter.getValue(i)));
369    }
370  0 break;
371  0 case SearchInfo.ILIKE:
372  0 for (int i = 0; i < filter.getValues().length; i++) {
373  0 criteria.add(Expression.ilike(filter.getColumn(), filter.getValue(i)));
374    }
375  0 break;
376    }
377    }
378  0 if (info.getOrder() != null && info.getOrder().length() > 0) {
379  0 if (info.isDescendant()) {
380  0 criteria.addOrder(Order.desc(info.getOrder()));
381    } else {
382  0 criteria.addOrder(Order.asc(info.getOrder()));
383    }
384    }
385  0 return criteria;
386    }
387   
388    /**
389    * TODO documentation
390    *
391    * @throws DAOException
392    */
 
393  0 toggle public void begin() throws DAOException {
394  0 if (logger.isDebugEnabled()) {
395  0 logger.debug("begin() - start");
396    }
397  0 if (BusinessObjectFactory.transaction.get() == null) {
398  0 try {
399  0 BusinessObjectFactory.transaction.set(this.current().beginTransaction());
400    } catch (HibernateException he) {
401    logger.error("begin() - error", he);
402    throw new DAOException("errors.session.begin", he);
403    }
404    } else {
405  0 logger.warn("begin() - transaction already started");
406    }
407    }
408   
409    /**
410    * TODO documentation
411    *
412    * @throws DAOException
413    */
 
414  0 toggle public void commit() throws DAOException {
415  0 if (logger.isDebugEnabled()) {
416  0 logger.debug("commit() - start");
417    }
418  0 Transaction transaction = (Transaction)BusinessObjectFactory.transaction.get();
419  0 try {
420  0 transaction.commit();
421    } catch (HibernateException he) {
422    logger.error("commit() - error", he);
423    throw new DAOException("errors.session.commit", he);
424    } catch (NullPointerException npe) {
425    logger.warn("commit() - transaction never started");
426    throw new DAOException("errors.session.commit");
427    } finally {
428  0 BusinessObjectFactory.transaction.set(null);
429    }
430    }
431   
432    /**
433    * TODO documentation
434    *
435    * @throws DAOException
436    */
 
437  0 toggle public void rollback() throws DAOException {
438  0 if (logger.isDebugEnabled()) {
439  0 logger.debug("rollback() - start");
440    }
441  0 Transaction transaction = (Transaction)BusinessObjectFactory.transaction.get();
442  0 try {
443  0 transaction.rollback();
444    } catch (HibernateException he) {
445    logger.error("rollback() - error", he);
446    throw new DAOException("errors.session.rollback", he);
447    } catch (NullPointerException npe) {
448    logger.warn("rollback() - transaction never started", npe);
449    } finally {
450  0 BusinessObjectFactory.transaction.set(null);
451    }
452    }
453   
454   
455    /**
456    * TODO documentation
457    */
 
458    public class Paginator extends net.smartlab.web.page.Paginator implements Collection {
459   
460    /**
461    * Logger for this class
462    */
463    private final Log logger = LogFactory.getLog(Paginator.class);
464   
465    /**
466    * References the Hibernate query or criteria passed to the constructor.
467    * It cannot be null.
468    */
469    private Object statement;
470   
471   
472    /**
473    * Constructs an instance on an Hibernate criteria with an unlimited
474    * number of items per page and an unlimited number of pages displayed.
475    *
476    * @param criteria the Hibernate criteria whose results must be
477    * paginated.
478    * @throws HibernateException if something wrong occurs accessing the
479    * database.
480    */
 
481  0 toggle public Paginator(Criteria criteria) throws HibernateException {
482  0 this(criteria, Paginator.UNLIMITED_ITEMS, Paginator.UNLIMITED_PAGES);
483    }
484   
485    /**
486    * Constructs an instance on an Hibernate criteria with the specified
487    * number of elements per page and the specified number of pages
488    * displayed.
489    *
490    * @param criteria the Hibernate criteria whose results must be
491    * paginated.
492    * @param size the number of elements per page.
493    * @param pages the number of pages to be displayed for quick
494    * navigation.
495    * @throws HibernateException if something wrong occurs accessing the
496    * database.
497    */
 
498  0 toggle public Paginator(Criteria criteria, int size, int pages) throws HibernateException {
499  0 super(size, pages);
500  0 this.statement = criteria;
501  0 ResultTransformer rt = ((CriteriaImpl)criteria).getResultTransformer();
502  0 List temp = new ArrayList();
503  0 Iterator orderings = ((CriteriaImpl)criteria).iterateOrderings();
504  0 while (orderings.hasNext()) {
505  0 Order ordering = ((CriteriaImpl.OrderEntry)orderings.next()).getOrder();
506  0 orderings.remove();
507  0 temp.add(ordering);
508    }
509  0 criteria.setProjection(Projections.rowCount());
510  0 this.setCount(((Integer)criteria.uniqueResult()).intValue());
511  0 criteria.setProjection(null);
512  0 if (rt == null) {
513  0 rt = Criteria.ROOT_ENTITY;
514    }
515  0 criteria.setResultTransformer(rt);
516  0 orderings = temp.iterator();
517  0 while (orderings.hasNext()) {
518  0 criteria.addOrder((Order)orderings.next());
519    }
520  0 this.setSize(size);
521    }
522   
523    /**
524    * Constructs an instance on an Hibernate query with an unlimited number
525    * of items per page and an unlimited number of pages displayed.
526    *
527    * @param query the Hibernate query whose results must be paginated.
528    * @throws DAOException if something wrong occurs accessing the
529    * underling data layer.
530    * @throws HibernateException if something wrong occurs accessing the
531    * database.
532    */
 
533  0 toggle public Paginator(Query query) throws DAOException, HibernateException {
534  0 this(query, Paginator.UNLIMITED_ITEMS, Paginator.UNLIMITED_PAGES);
535    }
536   
537    /**
538    * Constructs an instance on an Hibernate query with the specified
539    * number of elements per page and the specified number of pages
540    * displayed. FIXME the computation of rowCount is still slow on long
541    * lists.
542    *
543    * @param query the Hibernate query whose results must be paginated.
544    * @param size the number of elements per page.
545    * @param pages the number of pages to be displayed for quick
546    * navigation.
547    * @throws DAOException if something wrong occurs accessing the
548    * underling data layer.
549    * @throws HibernateException if something wrong occurs accessing the
550    * database.
551    */
 
552  0 toggle public Paginator(Query query, int size, int pages) throws DAOException, HibernateException {
553  0 super(size, pages);
554  0 this.statement = query;
555  0 int queryCount = query.count();
556  0 this.setCount(queryCount);
557  0 this.setSize(size);
558    }
559   
560    /**
561    * @see net.smartlab.web.page.Paginator#setPage(int)
562    */
 
563  0 toggle public void setPage(int page) {
564  0 if (logger.isDebugEnabled()) {
565  0 logger.debug("setPage(page = " + page + ") - start");
566    }
567  0 if (statement instanceof Criteria) {
568  0 ((Criteria)this.statement).setFirstResult((page - 1) * super.getPageSize());
569    } else {
570  0 ((Query)this.statement).setFirstResult((page - 1) * super.getPageSize());
571    }
572  0 super.setPage(page);
573    }
574   
575    /**
576    * TODO documentation
577    *
578    * @param size
579    */
 
580  0 toggle public void setSize(int size) {
581  0 if (logger.isDebugEnabled()) {
582  0 logger.debug("setSize(size = " + size + ") - start");
583    }
584  0 if (size != UNLIMITED_ITEMS) {
585  0 super.setPageSize(size);
586  0 if (statement instanceof Criteria) {
587  0 ((Criteria)this.statement).setMaxResults(size);
588    } else {
589  0 ((Query)this.statement).setMaxResults(size);
590    }
591    } else {
592  0 super.setPageSize(this.getCount());
593    }
594    }
595   
596    /**
597    * @see net.smartlab.web.page.Paginator#setArray()
598    */
 
599  0 toggle protected void setArray() {
600  0 if (logger.isDebugEnabled()) {
601  0 logger.debug("setArray() - start");
602    }
603  0 try {
604  0 Iterator elements = null;
605  0 if (statement instanceof Criteria) {
606  0 elements = ((Criteria)this.statement).list().iterator();
607    } else {
608  0 elements = ((Query)this.statement).list().iterator();
609    }
610  0 for (int i = 0; i < array.length && elements.hasNext(); i++) {
611  0 array[i] = elements.next();
612    }
613    } catch (HibernateException he) {
614    logger.error("setArray() - error", he);
615    }
616    }
617   
618    /**
619    * @see java.util.Collection#add(java.lang.Object)
620    */
 
621  0 toggle public boolean add(Object obj) {
622  0 throw new UnsupportedOperationException();
623    }
624   
625    /**
626    * @see java.util.Collection#addAll(java.util.Collection)
627    */
 
628  0 toggle public boolean addAll(Collection collection) {
629  0 throw new UnsupportedOperationException();
630    }
631   
632    /**
633    * @see java.util.Collection#clear()
634    */
 
635  0 toggle public void clear() {
636  0 throw new UnsupportedOperationException();
637    }
638   
639    /**
640    * @see java.util.Collection#contains(java.lang.Object)
641    */
 
642  0 toggle public boolean contains(Object item) {
643  0 if (logger.isDebugEnabled()) {
644  0 logger.debug("contains(item = " + item + ") - start");
645    }
646  0 for (int i = 0; i < array.length; i++) {
647  0 if (array[i].equals(item)) {
648  0 return true;
649    }
650    }
651  0 return false;
652    }
653   
654    /**
655    * @see java.util.Collection#containsAll(java.util.Collection)
656    */
 
657  0 toggle public boolean containsAll(Collection item) {
658  0 throw new UnsupportedOperationException();
659    }
660   
661    /**
662    * @see java.util.Collection#isEmpty()
663    */
 
664  0 toggle public boolean isEmpty() {
665  0 return super.getCount() == 0;
666    }
667   
668    /**
669    * @see java.util.Collection#iterator()
670    */
 
671  0 toggle public Iterator iterator() {
672  0 return this;
673    }
674   
675    /**
676    * @see java.util.Collection#remove(java.lang.Object)
677    */
 
678  0 toggle public boolean remove(Object obj) {
679  0 throw new UnsupportedOperationException();
680    }
681   
682    /**
683    * @see java.util.Collection#removeAll(java.util.Collection)
684    */
 
685  0 toggle public boolean removeAll(Collection collection) {
686  0 throw new UnsupportedOperationException();
687    }
688   
689    /**
690    * @see java.util.Collection#retainAll(java.util.Collection)
691    */
 
692  0 toggle public boolean retainAll(Collection collection) {
693  0 throw new UnsupportedOperationException();
694    }
695   
696    /**
697    * @see java.util.Collection#size()
698    */
 
699  0 toggle public int size() {
700  0 return super.getCount();
701    }
702   
703    /**
704    * @see java.util.Collection#toArray()
705    */
 
706  0 toggle public Object[] toArray() {
707  0 return array;
708    }
709   
710    /**
711    * @see java.util.Collection#toArray(java.lang.Object[])
712    */
 
713  0 toggle public Object[] toArray(Object[] array) {
714  0 return this.array;
715    }
716    }
717    }