KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > campware > cream > om > BaseTurbinePermissionPeer


1 package org.campware.cream.om;
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.campware.cream.om.map.*;
32
33
34 /**
35  * This class was autogenerated by Torque on:
36  *
37  * [Wed May 04 09:10:56 CEST 2005]
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 = "cream";
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   
66     static
67     {
68           PERMISSION_ID = "TURBINE_PERMISSION.PERMISSION_ID";
69           PERMISSION_NAME = "TURBINE_PERMISSION.PERMISSION_NAME";
70           if (Torque.isInit())
71         {
72             try
73             {
74                 getMapBuilder(TurbinePermissionMapBuilder.CLASS_NAME);
75             }
76             catch (Exception JavaDoc e)
77             {
78                 log.error("Could not initialize Peer", e);
79             }
80         }
81         else
82         {
83             Torque.registerMapBuilder(TurbinePermissionMapBuilder.CLASS_NAME);
84         }
85     }
86  
87     /** number of columns for this peer */
88     public static final int numColumns = 2;
89
90     /** A class that can be returned by this peer. */
91     protected static final String JavaDoc CLASSNAME_DEFAULT =
92         "org.campware.cream.om.TurbinePermission";
93
94     /** A class that can be returned by this peer. */
95     protected static final Class JavaDoc CLASS_DEFAULT = initClass(CLASSNAME_DEFAULT);
96
97     /**
98      * Class object initialization method.
99      *
100      * @param className name of the class to initialize
101      * @return the initialized class
102      */

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

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

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

195     public static ObjectKey doInsert(Criteria criteria, Connection JavaDoc con)
196         throws TorqueException
197     {
198               
199         setDbName(criteria);
200
201         if (con == null)
202         {
203             return BasePeer.doInsert(criteria);
204         }
205         else
206         {
207             return BasePeer.doInsert(criteria, con);
208         }
209     }
210
211     /**
212      * Add all the columns needed to create a new object.
213      *
214      * @param criteria object containing the columns to add.
215      * @throws TorqueException Any exceptions caught during processing will be
216      * rethrown wrapped into a TorqueException.
217      */

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

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

267     public static void populateObject(Record row,
268                                       int offset,
269                                       TurbinePermission obj)
270         throws TorqueException
271     {
272         try
273         {
274                 obj.setPermissionId(row.getValue(offset + 0).asInt());
275                   obj.setName(row.getValue(offset + 1).asString());
276               }
277         catch (DataSetException e)
278         {
279             throw new TorqueException(e);
280         }
281     }
282
283     /**
284      * Method to do selects.
285      *
286      * @param criteria object used to create the SELECT statement.
287      * @return List of selected Objects
288      * @throws TorqueException Any exceptions caught during processing will be
289      * rethrown wrapped into a TorqueException.
290      */

291     public static List JavaDoc doSelect(Criteria criteria) throws TorqueException
292     {
293         return populateObjects(doSelectVillageRecords(criteria));
294     }
295
296     /**
297      * Method to do selects within a transaction.
298      *
299      * @param criteria object used to create the SELECT statement.
300      * @param con the connection to use
301      * @return List of selected Objects
302      * @throws TorqueException Any exceptions caught during processing will be
303      * rethrown wrapped into a TorqueException.
304      */

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

321     public static List JavaDoc doSelectVillageRecords(Criteria criteria)
322         throws TorqueException
323     {
324         return BaseTurbinePermissionPeer
325             .doSelectVillageRecords(criteria, (Connection JavaDoc) null);
326     }
327
328     /**
329      * Grabs the raw Village records to be formed into objects.
330      * This method should be used for transactions
331      *
332      * @param criteria object used to create the SELECT statement.
333      * @param con the connection to use
334      * @throws TorqueException Any exceptions caught during processing will be
335      * rethrown wrapped into a TorqueException.
336      */

337     public static List JavaDoc doSelectVillageRecords(Criteria criteria, Connection JavaDoc con)
338         throws TorqueException
339     {
340         if (criteria.getSelectColumns().size() == 0)
341         {
342             addSelectColumns(criteria);
343         }
344
345               
346         setDbName(criteria);
347
348         // BasePeer returns a List of Value (Village) arrays. The array
349
// order follows the order columns were placed in the Select clause.
350
if (con == null)
351         {
352             return BasePeer.doSelect(criteria);
353         }
354         else
355         {
356             return BasePeer.doSelect(criteria, con);
357         }
358     }
359
360     /**
361      * The returned List will contain objects of the default type or
362      * objects that inherit from the default.
363      *
364      * @throws TorqueException Any exceptions caught during processing will be
365      * rethrown wrapped into a TorqueException.
366      */

367     public static List JavaDoc populateObjects(List JavaDoc records)
368         throws TorqueException
369     {
370         List JavaDoc results = new ArrayList JavaDoc(records.size());
371
372         // populate the object(s)
373
for (int i = 0; i < records.size(); i++)
374         {
375             Record row = (Record) records.get(i);
376               results.add(TurbinePermissionPeer.row2Object(row, 1,
377                 TurbinePermissionPeer.getOMClass()));
378           }
379         return results;
380     }
381  
382
383     /**
384      * The class that the Peer will make instances of.
385      * If the BO is abstract then you must implement this method
386      * in the BO.
387      *
388      * @throws TorqueException Any exceptions caught during processing will be
389      * rethrown wrapped into a TorqueException.
390      */

391     public static Class JavaDoc getOMClass()
392         throws TorqueException
393     {
394         return CLASS_DEFAULT;
395     }
396
397     /**
398      * Method to do updates.
399      *
400      * @param criteria object containing data that is used to create the UPDATE
401      * statement.
402      * @throws TorqueException Any exceptions caught during processing will be
403      * rethrown wrapped into a TorqueException.
404      */

405     public static void doUpdate(Criteria criteria) throws TorqueException
406     {
407          BaseTurbinePermissionPeer
408             .doUpdate(criteria, (Connection JavaDoc) null);
409     }
410
411     /**
412      * Method to do updates. This method is to be used during a transaction,
413      * otherwise use the doUpdate(Criteria) method. It will take care of
414      * the connection details internally.
415      *
416      * @param criteria object containing data that is used to create the UPDATE
417      * statement.
418      * @param con the connection to use
419      * @throws TorqueException Any exceptions caught during processing will be
420      * rethrown wrapped into a TorqueException.
421      */

422     public static void doUpdate(Criteria criteria, Connection JavaDoc con)
423         throws TorqueException
424     {
425         Criteria selectCriteria = new Criteria(DATABASE_NAME, 2);
426                    selectCriteria.put(PERMISSION_ID, criteria.remove(PERMISSION_ID));
427                 
428         setDbName(criteria);
429
430         if (con == null)
431         {
432             BasePeer.doUpdate(selectCriteria, criteria);
433         }
434         else
435         {
436             BasePeer.doUpdate(selectCriteria, criteria, con);
437         }
438     }
439
440     /**
441      * Method to do deletes.
442      *
443      * @param criteria object containing data that is used DELETE from database.
444      * @throws TorqueException Any exceptions caught during processing will be
445      * rethrown wrapped into a TorqueException.
446      */

447      public static void doDelete(Criteria criteria) throws TorqueException
448      {
449          TurbinePermissionPeer
450             .doDelete(criteria, (Connection JavaDoc) null);
451      }
452
453     /**
454      * Method to do deletes. This method is to be used during a transaction,
455      * otherwise use the doDelete(Criteria) method. It will take care of
456      * the connection details internally.
457      *
458      * @param criteria object containing data that is used DELETE from database.
459      * @param con the connection to use
460      * @throws TorqueException Any exceptions caught during processing will be
461      * rethrown wrapped into a TorqueException.
462      */

463      public static void doDelete(Criteria criteria, Connection JavaDoc con)
464         throws TorqueException
465      {
466               
467         setDbName(criteria);
468
469         if (con == null)
470         {
471             BasePeer.doDelete(criteria);
472         }
473         else
474         {
475             BasePeer.doDelete(criteria, con);
476         }
477      }
478
479     /**
480      * Method to do selects
481      *
482      * @throws TorqueException Any exceptions caught during processing will be
483      * rethrown wrapped into a TorqueException.
484      */

485     public static List JavaDoc doSelect(TurbinePermission obj) throws TorqueException
486     {
487         return doSelect(buildSelectCriteria(obj));
488     }
489
490     /**
491      * Method to do inserts
492      *
493      * @throws TorqueException Any exceptions caught during processing will be
494      * rethrown wrapped into a TorqueException.
495      */

496     public static void doInsert(TurbinePermission obj) throws TorqueException
497     {
498           obj.setPrimaryKey(doInsert(buildCriteria(obj)));
499           obj.setNew(false);
500         obj.setModified(false);
501     }
502
503     /**
504      * @param obj the data object to update in the database.
505      * @throws TorqueException Any exceptions caught during processing will be
506      * rethrown wrapped into a TorqueException.
507      */

508     public static void doUpdate(TurbinePermission obj) throws TorqueException
509     {
510         doUpdate(buildCriteria(obj));
511         obj.setModified(false);
512     }
513
514     /**
515      * @param obj the data object to delete in the database.
516      * @throws TorqueException Any exceptions caught during processing will be
517      * rethrown wrapped into a TorqueException.
518      */

519     public static void doDelete(TurbinePermission obj) throws TorqueException
520     {
521         doDelete(buildSelectCriteria(obj));
522     }
523
524     /**
525      * Method to do inserts. This method is to be used during a transaction,
526      * otherwise use the doInsert(TurbinePermission) method. It will take
527      * care of the connection details internally.
528      *
529      * @param obj the data object to insert into the database.
530      * @param con the connection to use
531      * @throws TorqueException Any exceptions caught during processing will be
532      * rethrown wrapped into a TorqueException.
533      */

534     public static void doInsert(TurbinePermission obj, Connection JavaDoc con)
535         throws TorqueException
536     {
537           obj.setPrimaryKey(doInsert(buildCriteria(obj), con));
538           obj.setNew(false);
539         obj.setModified(false);
540     }
541
542     /**
543      * Method to do update. This method is to be used during a transaction,
544      * otherwise use the doUpdate(TurbinePermission) method. It will take
545      * care of the connection details internally.
546      *
547      * @param obj the data object to update in the database.
548      * @param con the connection to use
549      * @throws TorqueException Any exceptions caught during processing will be
550      * rethrown wrapped into a TorqueException.
551      */

552     public static void doUpdate(TurbinePermission obj, Connection JavaDoc con)
553         throws TorqueException
554     {
555         doUpdate(buildCriteria(obj), con);
556         obj.setModified(false);
557     }
558
559     /**
560      * Method to delete. This method is to be used during a transaction,
561      * otherwise use the doDelete(TurbinePermission) method. It will take
562      * care of the connection details internally.
563      *
564      * @param obj the data object to delete in the database.
565      * @param con the connection to use
566      * @throws TorqueException Any exceptions caught during processing will be
567      * rethrown wrapped into a TorqueException.
568      */

569     public static void doDelete(TurbinePermission obj, Connection JavaDoc con)
570         throws TorqueException
571     {
572         doDelete(buildSelectCriteria(obj), con);
573     }
574
575     /**
576      * Method to do deletes.
577      *
578      * @param pk ObjectKey that is used DELETE from database.
579      * @throws TorqueException Any exceptions caught during processing will be
580      * rethrown wrapped into a TorqueException.
581      */

582     public static void doDelete(ObjectKey pk) throws TorqueException
583     {
584         BaseTurbinePermissionPeer
585            .doDelete(pk, (Connection JavaDoc) null);
586     }
587
588     /**
589      * Method to delete. This method is to be used during a transaction,
590      * otherwise use the doDelete(ObjectKey) method. It will take
591      * care of the connection details internally.
592      *
593      * @param pk the primary key for the object to delete in the database.
594      * @param con the connection to use
595      * @throws TorqueException Any exceptions caught during processing will be
596      * rethrown wrapped into a TorqueException.
597      */

598     public static void doDelete(ObjectKey pk, Connection JavaDoc con)
599         throws TorqueException
600     {
601         doDelete(buildCriteria(pk), con);
602     }
603
604     /** Build a Criteria object from an ObjectKey */
605     public static Criteria buildCriteria( ObjectKey pk )
606     {
607         Criteria criteria = new Criteria();
608               criteria.add(PERMISSION_ID, pk);
609           return criteria;
610      }
611
612     /** Build a Criteria object from the data object for this peer */
613     public static Criteria buildCriteria( TurbinePermission obj )
614     {
615         Criteria criteria = new Criteria(DATABASE_NAME);
616               if (!obj.isNew())
617             criteria.add(PERMISSION_ID, obj.getPermissionId());
618               criteria.add(PERMISSION_NAME, obj.getName());
619           return criteria;
620     }
621
622     /** Build a Criteria object from the data object for this peer, skipping all binary columns */
623     public static Criteria buildSelectCriteria( TurbinePermission obj )
624     {
625         Criteria criteria = new Criteria(DATABASE_NAME);
626               if (!obj.isNew())
627                     criteria.add(PERMISSION_ID, obj.getPermissionId());
628                           criteria.add(PERMISSION_NAME, obj.getName());
629               return criteria;
630     }
631  
632     
633         /**
634      * Retrieve a single object by pk
635      *
636      * @param pk the primary key
637      * @throws TorqueException Any exceptions caught during processing will be
638      * rethrown wrapped into a TorqueException.
639      * @throws NoRowsException Primary key was not found in database.
640      * @throws TooManyRowsException Primary key was not found in database.
641      */

642     public static TurbinePermission retrieveByPK(int pk)
643         throws TorqueException, NoRowsException, TooManyRowsException
644     {
645         return retrieveByPK(SimpleKey.keyFor(pk));
646     }
647
648     /**
649      * Retrieve a single object by pk
650      *
651      * @param pk the primary key
652      * @param con the connection to use
653      * @throws TorqueException Any exceptions caught during processing will be
654      * rethrown wrapped into a TorqueException.
655      * @throws NoRowsException Primary key was not found in database.
656      * @throws TooManyRowsException Primary key was not found in database.
657      */

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

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

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

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

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

784     protected static TableMap getTableMap()
785         throws TorqueException
786     {
787         return Torque.getDatabaseMap(DATABASE_NAME).getTable(TABLE_NAME);
788     }
789    
790     private static void setDbName(Criteria crit)
791     {
792         // Set the correct dbName if it has not been overridden
793
// crit.getDbName will return the same object if not set to
794
// another value so == check is okay and faster
795
if (crit.getDbName() == Torque.getDefaultDB())
796         {
797             crit.setDbName(DATABASE_NAME);
798         }
799     }
800 }
801
Popular Tags