KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > jetspeed > om > security > turbine > BaseTurbinePermissionPeer


1 package org.apache.jetspeed.om.security.turbine;
2
3 import java.math.BigDecimal JavaDoc;
4 import java.sql.Connection JavaDoc;
5 import java.sql.SQLException JavaDoc;
6 import java.util.ArrayList JavaDoc;
7 import java.util.Date JavaDoc;
8 import java.util.Iterator JavaDoc;
9 import java.util.LinkedList JavaDoc;
10 import java.util.List JavaDoc;
11
12 import org.apache.torque.NoRowsException;
13 import org.apache.torque.TooManyRowsException;
14 import org.apache.torque.Torque;
15 import org.apache.torque.TorqueException;
16 import org.apache.torque.map.MapBuilder;
17 import org.apache.torque.map.TableMap;
18 import org.apache.torque.om.DateKey;
19 import org.apache.torque.om.NumberKey;
20 import org.apache.torque.om.StringKey;
21 import org.apache.torque.om.ObjectKey;
22 import org.apache.torque.om.SimpleKey;
23 import org.apache.torque.util.BasePeer;
24 import org.apache.torque.util.Criteria;
25
26 import com.workingdogs.village.DataSetException;
27 import com.workingdogs.village.QueryDataSet;
28 import com.workingdogs.village.Record;
29
30 // Local classes
31
import org.apache.jetspeed.om.security.turbine.map.*;
32
33
34 /**
35  * This class was autogenerated by Torque on:
36  *
37  * [Thu Apr 22 15:30:48 PDT 2004]
38  *
39  */

40 public abstract class BaseTurbinePermissionPeer
41     extends BasePeer
42 {
43
44     /** the default database name for this class */
45     public static final String JavaDoc DATABASE_NAME = "default";
46
47      /** the table name for this class */
48     public static final String JavaDoc TABLE_NAME = "TURBINE_PERMISSION";
49
50     /**
51      * @return the map builder for this peer
52      * @throws TorqueException Any exceptions caught during processing will be
53      * rethrown wrapped into a TorqueException.
54      */

55     public static MapBuilder getMapBuilder()
56         throws TorqueException
57     {
58         return getMapBuilder(TurbinePermissionMapBuilder.CLASS_NAME);
59     }
60
61       /** the column name for the PERMISSION_ID field */
62     public static final String JavaDoc PERMISSION_ID;
63       /** the column name for the PERMISSION_NAME field */
64     public static final String JavaDoc PERMISSION_NAME;
65       /** the column name for the OBJECTDATA field */
66     public static final String JavaDoc OBJECTDATA;
67   
68     static
69     {
70           PERMISSION_ID = "TURBINE_PERMISSION.PERMISSION_ID";
71           PERMISSION_NAME = "TURBINE_PERMISSION.PERMISSION_NAME";
72           OBJECTDATA = "TURBINE_PERMISSION.OBJECTDATA";
73           if (Torque.isInit())
74         {
75             try
76             {
77                 getMapBuilder();
78             }
79             catch (Exception JavaDoc e)
80             {
81                 log.error("Could not initialize Peer", e);
82             }
83         }
84         else
85         {
86             Torque.registerMapBuilder(TurbinePermissionMapBuilder.CLASS_NAME);
87         }
88     }
89  
90     /** number of columns for this peer */
91     public static final int numColumns = 3;
92
93     /** A class that can be returned by this peer. */
94     protected static final String JavaDoc CLASSNAME_DEFAULT =
95         "org.apache.jetspeed.om.security.turbine.TurbinePermission";
96
97     /** A class that can be returned by this peer. */
98     protected static final Class JavaDoc CLASS_DEFAULT = initClass(CLASSNAME_DEFAULT);
99
100     /**
101      * Class object initialization method.
102      *
103      * @param className name of the class to initialize
104      * @return the initialized class
105      */

106     private static Class JavaDoc initClass(String JavaDoc className)
107     {
108         Class JavaDoc c = null;
109         try
110         {
111             c = Class.forName(className);
112         }
113         catch (Throwable JavaDoc t)
114         {
115             log.error("A FATAL ERROR has occurred which should not "
116                 + "have happened under any circumstance. Please notify "
117                 + "the Torque developers <turbine-torque-dev@jakarta.apache.org> "
118                 + "and give as many details as possible (including the error "
119                 + "stack trace).", t);
120
121             // Error objects should always be propogated.
122
if (t instanceof Error JavaDoc)
123             {
124                 throw (Error JavaDoc) t.fillInStackTrace();
125             }
126         }
127         return c;
128     }
129
130     /**
131      * Get the list of objects for a ResultSet. Please not that your
132      * resultset MUST return columns in the right order. You can use
133      * getFieldNames() in BaseObject to get the correct sequence.
134      *
135      * @param results the ResultSet
136      * @return the list of objects
137      * @throws TorqueException Any exceptions caught during processing will be
138      * rethrown wrapped into a TorqueException.
139      */

140     public static List JavaDoc resultSet2Objects(java.sql.ResultSet JavaDoc results)
141             throws TorqueException
142     {
143         try
144         {
145             QueryDataSet qds = null;
146             List JavaDoc rows = null;
147             try
148             {
149                 qds = new QueryDataSet(results);
150                 rows = getSelectResults(qds);
151             }
152             finally
153             {
154                 if (qds != null)
155                 {
156                     qds.close();
157                 }
158             }
159
160             return populateObjects(rows);
161         }
162         catch (SQLException JavaDoc e)
163         {
164             throw new TorqueException(e);
165         }
166         catch (DataSetException e)
167         {
168             throw new TorqueException(e);
169         }
170     }
171
172
173   
174     /**
175      * Method to do inserts.
176      *
177      * @param criteria object used to create the INSERT statement.
178      * @throws TorqueException Any exceptions caught during processing will be
179      * rethrown wrapped into a TorqueException.
180      */

181     public static ObjectKey doInsert(Criteria criteria)
182         throws TorqueException
183     {
184         return BaseTurbinePermissionPeer
185             .doInsert(criteria, (Connection JavaDoc) null);
186     }
187
188     /**
189      * Method to do inserts. This method is to be used during a transaction,
190      * otherwise use the doInsert(Criteria) method. It will take care of
191      * the connection details internally.
192      *
193      * @param criteria object used to create the INSERT statement.
194      * @param con the connection to use
195      * @throws TorqueException Any exceptions caught during processing will be
196      * rethrown wrapped into a TorqueException.
197      */

198     public static ObjectKey doInsert(Criteria criteria, Connection JavaDoc con)
199         throws TorqueException
200     {
201                     
202         // Set the correct dbName if it has not been overridden
203
// criteria.getDbName will return the same object if not set to
204
// another value so == check is okay and faster
205
if (criteria.getDbName() == Torque.getDefaultDB())
206         {
207             criteria.setDbName(DATABASE_NAME);
208         }
209         if (con == null)
210         {
211             return BasePeer.doInsert(criteria);
212         }
213         else
214         {
215             return BasePeer.doInsert(criteria, con);
216         }
217     }
218
219     /**
220      * Add all the columns needed to create a new object.
221      *
222      * @param criteria object containing the columns to add.
223      * @throws TorqueException Any exceptions caught during processing will be
224      * rethrown wrapped into a TorqueException.
225      */

226     public static void addSelectColumns(Criteria criteria)
227             throws TorqueException
228     {
229           criteria.addSelectColumn(PERMISSION_ID);
230           criteria.addSelectColumn(PERMISSION_NAME);
231           criteria.addSelectColumn(OBJECTDATA);
232       }
233
234     /**
235      * Create a new object of type cls from a resultset row starting
236      * from a specified offset. This is done so that you can select
237      * other rows than just those needed for this object. You may
238      * for example want to create two objects from the same row.
239      *
240      * @throws TorqueException Any exceptions caught during processing will be
241      * rethrown wrapped into a TorqueException.
242      */

243     public static TurbinePermission row2Object(Record row,
244                                              int offset,
245                                              Class JavaDoc cls)
246         throws TorqueException
247     {
248         try
249         {
250             TurbinePermission obj = (TurbinePermission) cls.newInstance();
251             TurbinePermissionPeer.populateObject(row, offset, obj);
252                   obj.setModified(false);
253               obj.setNew(false);
254
255             return obj;
256         }
257         catch (InstantiationException JavaDoc e)
258         {
259             throw new TorqueException(e);
260         }
261         catch (IllegalAccessException JavaDoc e)
262         {
263             throw new TorqueException(e);
264         }
265     }
266
267     /**
268      * Populates an object from a resultset row starting
269      * from a specified offset. This is done so that you can select
270      * other rows than just those needed for this object. You may
271      * for example want to create two objects from the same row.
272      *
273      * @throws TorqueException Any exceptions caught during processing will be
274      * rethrown wrapped into a TorqueException.
275      */

276     public static void populateObject(Record row,
277                                       int offset,
278                                       TurbinePermission obj)
279         throws TorqueException
280     {
281         try
282         {
283                 obj.setPermissionId(row.getValue(offset + 0).asInt());
284                   obj.setPermissionName(row.getValue(offset + 1).asString());
285                   obj.setObjectdata(row.getValue(offset + 2).asBytes());
286               }
287         catch (DataSetException e)
288         {
289             throw new TorqueException(e);
290         }
291     }
292
293     /**
294      * Method to do selects.
295      *
296      * @param criteria object used to create the SELECT statement.
297      * @return List of selected Objects
298      * @throws TorqueException Any exceptions caught during processing will be
299      * rethrown wrapped into a TorqueException.
300      */

301     public static List JavaDoc doSelect(Criteria criteria) throws TorqueException
302     {
303         return populateObjects(doSelectVillageRecords(criteria));
304     }
305
306     /**
307      * Method to do selects within a transaction.
308      *
309      * @param criteria object used to create the SELECT statement.
310      * @param con the connection to use
311      * @return List of selected Objects
312      * @throws TorqueException Any exceptions caught during processing will be
313      * rethrown wrapped into a TorqueException.
314      */

315     public static List JavaDoc doSelect(Criteria criteria, Connection JavaDoc con)
316         throws TorqueException
317     {
318         return populateObjects(doSelectVillageRecords(criteria, con));
319     }
320
321     /**
322      * Grabs the raw Village records to be formed into objects.
323      * This method handles connections internally. The Record objects
324      * returned by this method should be considered readonly. Do not
325      * alter the data and call save(), your results may vary, but are
326      * certainly likely to result in hard to track MT bugs.
327      *
328      * @throws TorqueException Any exceptions caught during processing will be
329      * rethrown wrapped into a TorqueException.
330      */

331     public static List JavaDoc doSelectVillageRecords(Criteria criteria)
332         throws TorqueException
333     {
334         return BaseTurbinePermissionPeer
335             .doSelectVillageRecords(criteria, (Connection JavaDoc) null);
336     }
337
338     /**
339      * Grabs the raw Village records to be formed into objects.
340      * This method should be used for transactions
341      *
342      * @param con the connection to use
343      * @throws TorqueException Any exceptions caught during processing will be
344      * rethrown wrapped into a TorqueException.
345      */

346     public static List JavaDoc doSelectVillageRecords(Criteria criteria, Connection JavaDoc con)
347         throws TorqueException
348     {
349         if (criteria.getSelectColumns().size() == 0)
350         {
351             addSelectColumns(criteria);
352         }
353
354                     
355         // Set the correct dbName if it has not been overridden
356
// criteria.getDbName will return the same object if not set to
357
// another value so == check is okay and faster
358
if (criteria.getDbName() == Torque.getDefaultDB())
359         {
360             criteria.setDbName(DATABASE_NAME);
361         }
362         // BasePeer returns a List of Value (Village) arrays. The array
363
// order follows the order columns were placed in the Select clause.
364
if (con == null)
365         {
366             return BasePeer.doSelect(criteria);
367         }
368         else
369         {
370             return BasePeer.doSelect(criteria, con);
371         }
372     }
373
374     /**
375      * The returned List will contain objects of the default type or
376      * objects that inherit from the default.
377      *
378      * @throws TorqueException Any exceptions caught during processing will be
379      * rethrown wrapped into a TorqueException.
380      */

381     public static List JavaDoc populateObjects(List JavaDoc records)
382         throws TorqueException
383     {
384         List JavaDoc results = new ArrayList JavaDoc(records.size());
385
386         // populate the object(s)
387
for (int i = 0; i < records.size(); i++)
388         {
389             Record row = (Record) records.get(i);
390               results.add(TurbinePermissionPeer.row2Object(row, 1,
391                 TurbinePermissionPeer.getOMClass()));
392           }
393         return results;
394     }
395  
396
397     /**
398      * The class that the Peer will make instances of.
399      * If the BO is abstract then you must implement this method
400      * in the BO.
401      *
402      * @throws TorqueException Any exceptions caught during processing will be
403      * rethrown wrapped into a TorqueException.
404      */

405     public static Class JavaDoc getOMClass()
406         throws TorqueException
407     {
408         return CLASS_DEFAULT;
409     }
410
411     /**
412      * Method to do updates.
413      *
414      * @param criteria object containing data that is used to create the UPDATE
415      * statement.
416      * @throws TorqueException Any exceptions caught during processing will be
417      * rethrown wrapped into a TorqueException.
418      */

419     public static void doUpdate(Criteria criteria) throws TorqueException
420     {
421          BaseTurbinePermissionPeer
422             .doUpdate(criteria, (Connection JavaDoc) null);
423     }
424
425     /**
426      * Method to do updates. This method is to be used during a transaction,
427      * otherwise use the doUpdate(Criteria) method. It will take care of
428      * the connection details internally.
429      *
430      * @param criteria object containing data that is used to create the UPDATE
431      * statement.
432      * @param con the connection to use
433      * @throws TorqueException Any exceptions caught during processing will be
434      * rethrown wrapped into a TorqueException.
435      */

436     public static void doUpdate(Criteria criteria, Connection JavaDoc con)
437         throws TorqueException
438     {
439         Criteria selectCriteria = new Criteria(DATABASE_NAME, 2);
440                    selectCriteria.put(PERMISSION_ID, criteria.remove(PERMISSION_ID));
441                           
442         // Set the correct dbName if it has not been overridden
443
// criteria.getDbName will return the same object if not set to
444
// another value so == check is okay and faster
445
if (criteria.getDbName() == Torque.getDefaultDB())
446         {
447             criteria.setDbName(DATABASE_NAME);
448         }
449         if (con == null)
450         {
451             BasePeer.doUpdate(selectCriteria, criteria);
452         }
453         else
454         {
455             BasePeer.doUpdate(selectCriteria, criteria, con);
456         }
457     }
458
459     /**
460      * Method to do deletes.
461      *
462      * @param criteria object containing data that is used DELETE from database.
463      * @throws TorqueException Any exceptions caught during processing will be
464      * rethrown wrapped into a TorqueException.
465      */

466      public static void doDelete(Criteria criteria) throws TorqueException
467      {
468          BaseTurbinePermissionPeer
469             .doDelete(criteria, (Connection JavaDoc) null);
470      }
471
472     /**
473      * Method to do deletes. This method is to be used during a transaction,
474      * otherwise use the doDelete(Criteria) method. It will take care of
475      * the connection details internally.
476      *
477      * @param criteria object containing data that is used DELETE from database.
478      * @param con the connection to use
479      * @throws TorqueException Any exceptions caught during processing will be
480      * rethrown wrapped into a TorqueException.
481      */

482      public static void doDelete(Criteria criteria, Connection JavaDoc con)
483         throws TorqueException
484      {
485                     
486         // Set the correct dbName if it has not been overridden
487
// criteria.getDbName will return the same object if not set to
488
// another value so == check is okay and faster
489
if (criteria.getDbName() == Torque.getDefaultDB())
490         {
491             criteria.setDbName(DATABASE_NAME);
492         }
493         if (con == null)
494         {
495             BasePeer.doDelete(criteria);
496         }
497         else
498         {
499             BasePeer.doDelete(criteria, con);
500         }
501      }
502
503     /**
504      * Method to do selects
505      *
506      * @throws TorqueException Any exceptions caught during processing will be
507      * rethrown wrapped into a TorqueException.
508      */

509     public static List JavaDoc doSelect(TurbinePermission obj) throws TorqueException
510     {
511         return doSelect(buildCriteria(obj));
512     }
513
514     /**
515      * Method to do inserts
516      *
517      * @throws TorqueException Any exceptions caught during processing will be
518      * rethrown wrapped into a TorqueException.
519      */

520     public static void doInsert(TurbinePermission obj) throws TorqueException
521     {
522           obj.setPrimaryKey(doInsert(buildCriteria(obj)));
523           obj.setNew(false);
524         obj.setModified(false);
525     }
526
527     /**
528      * @param obj the data object to update in the database.
529      * @throws TorqueException Any exceptions caught during processing will be
530      * rethrown wrapped into a TorqueException.
531      */

532     public static void doUpdate(TurbinePermission obj) throws TorqueException
533     {
534         doUpdate(buildCriteria(obj));
535         obj.setModified(false);
536     }
537
538     /**
539      * @param obj the data object to delete in the database.
540      * @throws TorqueException Any exceptions caught during processing will be
541      * rethrown wrapped into a TorqueException.
542      */

543     public static void doDelete(TurbinePermission obj) throws TorqueException
544     {
545         doDelete(buildCriteria(obj));
546     }
547
548     /**
549      * Method to do inserts. This method is to be used during a transaction,
550      * otherwise use the doInsert(TurbinePermission) method. It will take
551      * care of the connection details internally.
552      *
553      * @param obj the data object to insert into the database.
554      * @param con the connection to use
555      * @throws TorqueException Any exceptions caught during processing will be
556      * rethrown wrapped into a TorqueException.
557      */

558     public static void doInsert(TurbinePermission obj, Connection JavaDoc con)
559         throws TorqueException
560     {
561           obj.setPrimaryKey(doInsert(buildCriteria(obj), con));
562           obj.setNew(false);
563         obj.setModified(false);
564     }
565
566     /**
567      * Method to do update. This method is to be used during a transaction,
568      * otherwise use the doUpdate(TurbinePermission) method. It will take
569      * care of the connection details internally.
570      *
571      * @param obj the data object to update in the database.
572      * @param con the connection to use
573      * @throws TorqueException Any exceptions caught during processing will be
574      * rethrown wrapped into a TorqueException.
575      */

576     public static void doUpdate(TurbinePermission obj, Connection JavaDoc con)
577         throws TorqueException
578     {
579         doUpdate(buildCriteria(obj), con);
580         obj.setModified(false);
581     }
582
583     /**
584      * Method to delete. This method is to be used during a transaction,
585      * otherwise use the doDelete(TurbinePermission) method. It will take
586      * care of the connection details internally.
587      *
588      * @param obj the data object to delete in the database.
589      * @param con the connection to use
590      * @throws TorqueException Any exceptions caught during processing will be
591      * rethrown wrapped into a TorqueException.
592      */

593     public static void doDelete(TurbinePermission obj, Connection JavaDoc con)
594         throws TorqueException
595     {
596         doDelete(buildCriteria(obj), con);
597     }
598
599     /**
600      * Method to do deletes.
601      *
602      * @param pk ObjectKey that is used DELETE from database.
603      * @throws TorqueException Any exceptions caught during processing will be
604      * rethrown wrapped into a TorqueException.
605      */

606     public static void doDelete(ObjectKey pk) throws TorqueException
607     {
608         BaseTurbinePermissionPeer
609            .doDelete(pk, (Connection JavaDoc) null);
610     }
611
612     /**
613      * Method to delete. This method is to be used during a transaction,
614      * otherwise use the doDelete(ObjectKey) method. It will take
615      * care of the connection details internally.
616      *
617      * @param pk the primary key for the object to delete in the database.
618      * @param con the connection to use
619      * @throws TorqueException Any exceptions caught during processing will be
620      * rethrown wrapped into a TorqueException.
621      */

622     public static void doDelete(ObjectKey pk, Connection JavaDoc con)
623         throws TorqueException
624     {
625         doDelete(buildCriteria(pk), con);
626     }
627
628     /** Build a Criteria object from an ObjectKey */
629     public static Criteria buildCriteria( ObjectKey pk )
630     {
631         Criteria criteria = new Criteria();
632               criteria.add(PERMISSION_ID, pk);
633           return criteria;
634      }
635
636     /** Build a Criteria object from the data object for this peer */
637     public static Criteria buildCriteria( TurbinePermission obj )
638     {
639         Criteria criteria = new Criteria(DATABASE_NAME);
640               if (!obj.isNew())
641                 criteria.add(PERMISSION_ID, obj.getPermissionId());
642                   criteria.add(PERMISSION_NAME, obj.getPermissionName());
643                   criteria.add(OBJECTDATA, obj.getObjectdata());
644           return criteria;
645     }
646  
647     
648         /**
649      * Retrieve a single object by pk
650      *
651      * @param pk the primary key
652      * @throws TorqueException Any exceptions caught during processing will be
653      * rethrown wrapped into a TorqueException.
654      * @throws NoRowsException Primary key was not found in database.
655      * @throws TooManyRowsException Primary key was not found in database.
656      */

657     public static TurbinePermission retrieveByPK(int pk)
658         throws TorqueException, NoRowsException, TooManyRowsException
659     {
660         return retrieveByPK(SimpleKey.keyFor(pk));
661     }
662   
663     /**
664      * Retrieve a single object by pk
665      *
666      * @param pk the primary key
667      * @throws TorqueException Any exceptions caught during processing will be
668      * rethrown wrapped into a TorqueException.
669      * @throws NoRowsException Primary key was not found in database.
670      * @throws TooManyRowsException Primary key was not found in database.
671      */

672     public static TurbinePermission retrieveByPK(ObjectKey pk)
673         throws TorqueException, NoRowsException, TooManyRowsException
674     {
675         Connection JavaDoc db = null;
676         TurbinePermission retVal = null;
677         try
678         {
679             db = Torque.getConnection(DATABASE_NAME);
680             retVal = retrieveByPK(pk, db);
681         }
682         finally
683         {
684             Torque.closeConnection(db);
685         }
686         return(retVal);
687     }
688
689     /**
690      * Retrieve a single object by pk
691      *
692      * @param pk the primary key
693      * @param con the connection to use
694      * @throws TorqueException Any exceptions caught during processing will be
695      * rethrown wrapped into a TorqueException.
696      * @throws NoRowsException Primary key was not found in database.
697      * @throws TooManyRowsException Primary key was not found in database.
698      */

699     public static TurbinePermission retrieveByPK(ObjectKey pk, Connection JavaDoc con)
700         throws TorqueException, NoRowsException, TooManyRowsException
701     {
702         Criteria criteria = buildCriteria(pk);
703         List JavaDoc v = doSelect(criteria, con);
704         if (v.size() == 0)
705         {
706             throw new NoRowsException("Failed to select a row.");
707         }
708         else if (v.size() > 1)
709         {
710             throw new TooManyRowsException("Failed to select only one row.");
711         }
712         else
713         {
714             return (TurbinePermission)v.get(0);
715         }
716     }
717
718     /**
719      * Retrieve a multiple objects by pk
720      *
721      * @param pks List of primary keys
722      * @throws TorqueException Any exceptions caught during processing will be
723      * rethrown wrapped into a TorqueException.
724      */

725     public static List JavaDoc retrieveByPKs(List JavaDoc pks)
726         throws TorqueException
727     {
728         Connection JavaDoc db = null;
729         List JavaDoc retVal = null;
730         try
731         {
732            db = Torque.getConnection(DATABASE_NAME);
733            retVal = retrieveByPKs(pks, db);
734         }
735         finally
736         {
737             Torque.closeConnection(db);
738         }
739         return(retVal);
740     }
741
742     /**
743      * Retrieve a multiple objects by pk
744      *
745      * @param pks List of primary keys
746      * @param dbcon the connection to use
747      * @throws TorqueException Any exceptions caught during processing will be
748      * rethrown wrapped into a TorqueException.
749      */

750     public static List JavaDoc retrieveByPKs( List JavaDoc pks, Connection JavaDoc dbcon )
751         throws TorqueException
752     {
753         List JavaDoc objs = null;
754         if (pks == null || pks.size() == 0)
755         {
756             objs = new LinkedList JavaDoc();
757         }
758         else
759         {
760             Criteria criteria = new Criteria();
761               criteria.addIn( PERMISSION_ID, pks );
762           objs = doSelect(criteria, dbcon);
763         }
764         return objs;
765     }
766
767  
768
769
770
771         
772   
773   
774     
775   
776       /**
777      * Returns the TableMap related to this peer. This method is not
778      * needed for general use but a specific application could have a need.
779      *
780      * @throws TorqueException Any exceptions caught during processing will be
781      * rethrown wrapped into a TorqueException.
782      */

783     protected static TableMap getTableMap()
784         throws TorqueException
785     {
786         return Torque.getDatabaseMap(DATABASE_NAME).getTable(TABLE_NAME);
787     }
788    }
789
Popular Tags