KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jahia > engines > containerlistproperties > ContainerListProperties_Engine


1 //
2
// ____.
3
// __/\ ______| |__/\. _______
4
// __ .____| | \ | +----+ \
5
// _______| /--| | | - \ _ | : - \_________
6
// \\______: :---| : : | : | \________>
7
// |__\---\_____________:______: :____|____:_____\
8
// /_____|
9
//
10
// . . . i n j a h i a w e t r u s t . . .
11
//
12

13 package org.jahia.engines.containerlistproperties;
14
15 import java.util.Enumeration JavaDoc;
16 import java.util.HashMap JavaDoc;
17 import java.util.Iterator JavaDoc;
18 import java.util.Properties JavaDoc;
19 import java.util.Set JavaDoc;
20 import java.util.Vector JavaDoc;
21
22 import javax.servlet.http.HttpSession JavaDoc;
23
24 import org.apache.regexp.RE;
25 import org.apache.regexp.RESyntaxException;
26
27 import org.jahia.content.ContentContainerListsXRefManager;
28 import org.jahia.data.JahiaData;
29 import org.jahia.data.containers.JahiaContainer;
30 import org.jahia.data.containers.JahiaContainerDefinition;
31 import org.jahia.data.containers.JahiaContainerList;
32 import org.jahia.data.containers.JahiaContentContainerFacade;
33 import org.jahia.data.events.JahiaEvent;
34 import org.jahia.data.fields.JahiaField;
35 import org.jahia.data.fields.JahiaFieldDefinition;
36 import org.jahia.data.fields.LoadFlags;
37 import org.jahia.engines.EngineToolBox;
38 import org.jahia.engines.JahiaEngine;
39 import org.jahia.engines.lock.LockEngine;
40 import org.jahia.engines.rights.ManageRights;
41 import org.jahia.exceptions.JahiaException;
42 import org.jahia.exceptions.JahiaForbiddenAccessException;
43 import org.jahia.exceptions.JahiaSessionExpirationException;
44 import org.jahia.params.ParamBean;
45 import org.jahia.registries.JahiaContainerDefinitionsRegistry;
46 import org.jahia.registries.ServicesRegistry;
47 import org.jahia.services.acl.JahiaBaseACL;
48 import org.jahia.services.audit.LoggingEventListener;
49 import org.jahia.services.containers.ContentContainerList;
50 import org.jahia.services.lock.LockKey;
51 import org.jahia.services.lock.LockService;
52 import org.jahia.services.pages.ContentPage;
53 import org.jahia.services.usermanager.JahiaUser;
54 import org.jahia.services.cache.HtmlCache;
55 import org.jahia.services.cache.CacheFactory;
56 import org.jahia.content.ContentContainerListKey;
57 import org.jahia.engines.categories.ManageCategories;
58
59
60 public class ContainerListProperties_Engine implements JahiaEngine {
61
62     /** The engine's name */
63     public static final String JavaDoc ENGINE_NAME = "containerlistproperties";
64
65     /** unique instance of this class */
66     private static ContainerListProperties_Engine instance = null;
67
68     /** logging */
69     private static final org.apache.log4j.Logger logger =
70             org.apache.log4j.Logger.getLogger (ContainerListProperties_Engine.class);
71
72     private static final String JavaDoc TEMPLATE_JSP = "container_list_properties";
73
74     private EngineToolBox toolBox;
75
76     /**
77      * Default constructor, creates a new <code>ContainerListProperties_Engine</code> instance.
78      */

79     private ContainerListProperties_Engine () {
80         logger.debug ("***** Starting " + ContainerListProperties_Engine.class.getName () +
81                 " engine *****");
82         toolBox = EngineToolBox.getInstance ();
83     } // end constructor
84

85     /**
86      * Returns the unique instance of this class
87      *
88      * @return the unique instance of this class
89      */

90     public static ContainerListProperties_Engine getInstance () {
91         if (instance == null) {
92             instance = new ContainerListProperties_Engine ();
93         }
94         return instance;
95     }
96
97     /**
98      * authoriseRender
99      */

100     public boolean authoriseRender (ParamBean jParams) {
101         return toolBox.authoriseRender (jParams);
102     }
103
104     /**
105      * renderLink
106      */

107     public String JavaDoc renderLink (ParamBean jParams, Object JavaDoc theObj)
108             throws JahiaException {
109         Properties JavaDoc extraParams = new Properties JavaDoc ();
110         String JavaDoc params = EMPTY_STRING;
111         ContentContainerList contentContainerList = (ContentContainerList)
112                 theObj;
113         JahiaContainerDefinition containerListDefinition =
114                 JahiaContainerDefinitionsRegistry.getInstance ().
115                 getDefinition (contentContainerList.getContainerListDefinitionID ());
116         String JavaDoc containerListName = containerListDefinition.getName ();
117         Vector JavaDoc ctnIDs = ServicesRegistry.getInstance ().
118                 getJahiaContainersService ().getctnidsInList (
119                         contentContainerList.getID (), jParams.getEntryLoadRequest ());
120         String JavaDoc scrollStr = Integer.toString (ctnIDs.size ()) + "_0";
121         if (scrollStr != null) {
122             if (scrollStr.length () > 0) {
123                 extraParams.setProperty ("ctnscroll_" + containerListName,
124                         scrollStr);
125             }
126         }
127         params += "?mode=display";
128         params += "&clid=" + contentContainerList.getID ();
129         return jParams.composeEngineUrl (ENGINE_NAME, extraParams, params);
130     }
131
132     /**
133      * needsJahiaData
134      */

135     public boolean needsJahiaData (ParamBean jParams) {
136         return false;
137     }
138
139     /**
140      * handles the engine actions
141      *
142      * @param jParams a ParamBean object
143      * @param jData a JahiaData object (not mandatory)
144      */

145     public void handleActions (ParamBean jParams, JahiaData jData)
146             throws JahiaException,
147             JahiaSessionExpirationException,
148             JahiaForbiddenAccessException {
149         // initalizes the hashmap
150
HashMap JavaDoc engineMap = initEngineMap (jParams);
151
152         // checks if the user has the right to display the engine
153
JahiaContainerList theContainerList = (JahiaContainerList) engineMap.
154                 get ("theContainerList");
155         JahiaUser theUser = jParams.getUser ();
156
157         if (theContainerList.checkAdminAccess (theUser)) {
158             engineMap.put ("adminAccess", Boolean.TRUE);
159             engineMap.put ("enableRightView", Boolean.TRUE);
160             engineMap.put ("writeAccess", Boolean.TRUE);
161
162         } else if (theContainerList.checkWriteAccess (theUser)) {
163             engineMap.put ("writeAccess", Boolean.TRUE);
164         }
165
166         if (engineMap.get ("writeAccess") != null) {
167             // #ifdef LOCK
168
LockService lockRegistry = ServicesRegistry.getInstance ().
169                     getLockService ();
170             if (jParams.settings ().areLocksActivated ()) {
171                 LockKey lockKey = LockKey.composeLockKey (LockKey.
172                         UPDATE_CONTAINERLIST_TYPE,
173                         theContainerList.getID (), theContainerList.getPageID ());
174                 if (lockRegistry.acquire (lockKey, jParams.getUser (),
175                         jParams.getSessionID (),
176                         jParams.getSession ().
177                         getMaxInactiveInterval ())) {
178                     // #endif
179
flushPageCacheThatDisplayContainerList (jParams, theContainerList);
180
181                     processLastScreen (jParams, engineMap);
182                     processCurrentScreen (jParams, engineMap);
183
184                     // #ifdef LOCK
185
} else {
186                     // Prerequisites are NOT completed ! Damned ! Redirect the JSP
187
// output to lock informations.
188
LockEngine.getInstance ().redirect (jParams, engineMap,
189                             lockKey);
190                 }
191             }
192             // #endif
193
} else {
194             throw new JahiaForbiddenAccessException ();
195         }
196         // displays the screen
197
toolBox.displayScreen (jParams, engineMap);
198
199     }
200
201
202     /**
203      * Retrieve the engine name.
204      *
205      * @return the engine name.
206      */

207     public final String JavaDoc getName () {
208         return ENGINE_NAME;
209     }
210
211
212     /**
213      * processes the last screen sent by the user
214      *
215      * @param jParams a ParamBean object
216      */

217     public void processLastScreen (ParamBean jParams, HashMap JavaDoc engineMap)
218             throws JahiaException,
219             JahiaForbiddenAccessException {
220         logger.debug ("started");
221
222         // Sets the container list
223
JahiaContainerList theContainerList = (JahiaContainerList) engineMap.
224                 get ("theContainerList");
225
226         // gets the last screen
227
// lastscreen = edit, rights, logs
228
String JavaDoc lastScreen = jParams.getRequest ().getParameter ("lastscreen");
229         engineMap.put ("lastscreen", lastScreen);
230         if (lastScreen == null) {
231             lastScreen = "edit";
232         }
233
234         // indicates to sub engines that we are processing last screen
235
int mode = JahiaEngine.UPDATE_MODE;
236
237         // dispatches to the appropriate sub engine
238
if (lastScreen.equals ("edit")) {
239             if (!updateContainerListData (jParams, engineMap)) {
240                 // if there was an error, come back to last screen
241
engineMap.put ("screen", lastScreen);
242                 engineMap.put ("jspSource", TEMPLATE_JSP);
243             }
244         } else if (lastScreen.equals ("rightsMgmt") ||
245                 lastScreen.equals ("ctneditview_rights")) {
246             if (engineMap.get ("adminAccess") != null) {
247                 engineMap.put ("logObjectType",
248                         Integer.toString (LoggingEventListener.
249                         CONTAINERLIST_TYPE));
250                 engineMap.put ("logObject", theContainerList);
251                 if (lastScreen.equals ("rightsMgmt")) {
252                     ManageRights.getInstance ().handleActions (jParams, mode,
253                             engineMap,
254                             theContainerList.getAclID ());
255                 } else {
256                     HashMap JavaDoc acls = (HashMap JavaDoc) engineMap.get ("fieldAcls");
257                     if (acls == null)
258                         return;
259                     String JavaDoc val = jParams.getRequest ().getParameter (
260                             "lastaclfield");
261                     Integer JavaDoc I = null;
262                     if (val != null) {
263                         I = (Integer JavaDoc) acls.get (val);
264                         if (I != null) {
265                             ManageRights.getInstance ().handleActions (jParams,
266                                     mode, engineMap,
267                                     I.intValue ());
268                         }
269                     }
270                 }
271             } else {
272                 throw new JahiaForbiddenAccessException ();
273             }
274         } else if (lastScreen.equals ("categories")) {
275             ManageCategories.getInstance ().handleActions (jParams, mode,
276                     engineMap, new ContentContainerListKey (theContainerList.getID ()),
277                     theContainerList.getDefinition (), false);
278         }
279     }
280
281     /**
282      * prepares the screen requested by the user
283      *
284      * @param jParams a ParamBean object
285      */

286     public void processCurrentScreen (ParamBean jParams, HashMap JavaDoc engineMap)
287             throws JahiaException,
288             JahiaForbiddenAccessException {
289         logger.debug ("Started");
290
291         // Sets the container list
292
JahiaContainerList theContainerList = (JahiaContainerList) engineMap.
293                 get ("theContainerList");
294
295         // gets the current screen
296
// screen = edit, rights, logs
297
String JavaDoc theScreen = (String JavaDoc) engineMap.get ("screen");
298
299         // indicates to sub engines that we are processing last screen
300
int mode = JahiaEngine.LOAD_MODE;
301
302         // #ifdef LOCK
303
LockKey lockKey = LockKey.composeLockKey (LockKey.
304                 UPDATE_CONTAINERLIST_TYPE,
305                 theContainerList.getID (),
306                 theContainerList.getPageID ());
307         LockService lockRegistry = ServicesRegistry.getInstance ().
308                 getLockService ();
309         // #endif
310

311         // dispatches to the appropriate sub engine
312
if (theScreen.equals ("edit")) {
313             loadContainerListData (jParams, engineMap);
314
315         } else if (theScreen.equals ("logs")) {
316             if (engineMap.get ("lastscreen") != null &&
317                     engineMap.get ("lastscreen").equals ("edit")) {
318                 // save container's rank
319
saveContainersRank (jParams, engineMap);
320             }
321             toolBox.loadLogData (jParams,
322                     LoggingEventListener.CONTAINERLIST_TYPE,
323                     engineMap);
324
325         } else if (theScreen.equals ("categories")) {
326             ManageCategories.getInstance ().handleActions (jParams, mode,
327                     engineMap, new ContentContainerListKey (theContainerList.getID ()),
328                     theContainerList.getDefinition (), false);
329
330         } else if (theScreen.equals ("rightsMgmt") ||
331                 theScreen.equals ("ctneditview_rights")) {
332
333             if (engineMap.get ("lastscreen") != null &&
334                     engineMap.get ("lastscreen").equals ("edit")) {
335                 // save container's rank
336
saveContainersRank (jParams, engineMap);
337             }
338             if (engineMap.get ("adminAccess") != null) {
339                 if (theScreen.equals ("rightsMgmt")) {
340                     ManageRights.getInstance ().handleActions (jParams, mode,
341                             engineMap,
342                             theContainerList.getAclID ());
343                 } else {
344                     logger.debug ("Step1");
345
346                     HashMap JavaDoc acls = (HashMap JavaDoc) engineMap.get ("fieldAcls");
347                     if (acls == null)
348                         return;
349                     String JavaDoc val = jParams.getRequest ().getParameter (
350                             "aclfieldname");
351                     logger.debug ("aclfieldname=" + val);
352
353                     Integer JavaDoc I = null;
354                     if (val == null) {
355                         // use the first
356
val = (String JavaDoc) engineMap.get ("fieldAclDefaultField");
357                     }
358                     if (val != null) {
359                         // store for JSP
360
engineMap.put ("aclfieldname", val);
361                         engineMap.put ("fieldAclDefaultField", val);
362                         I = (Integer JavaDoc) acls.get (val);
363                         if (I != null) {
364                             logger.debug ("Step3");
365                             ManageRights.getInstance ().handleActions (jParams,
366                                     mode, engineMap,
367                                     I.intValue ());
368                         }
369                     } else {
370                         engineMap.put ("aclfieldname", EMPTY_STRING);
371                         return;
372                     }
373                 }
374             } else {
375                 throw new JahiaForbiddenAccessException ();
376             }
377         } else if (theScreen.equals ("save") || theScreen.equals ("apply")) {
378
379             // #ifdef LOCK
380
// Did somebody steal the lock ? Panpan cucul !
381
if (jParams.settings ().areLocksActivated () &&
382                     lockRegistry.isStealedInContext (lockKey, jParams.getUser (),
383                             jParams.getSessionID ())) {
384                 engineMap.put ("screen",
385                         jParams.getRequest ().getParameter ("lastscreen"));
386                 engineMap.put ("jspSource", "apply");
387                 return;
388             }
389             // #endif
390

391             mode = JahiaEngine.SAVE_MODE;
392             // save the page info
393
ServicesRegistry.getInstance ().getJahiaContainersService ().
394                     saveContainerListInfo (theContainerList, 0);
395             if (engineMap.get ("lastscreen") != null &&
396                     engineMap.get ("lastscreen").equals ("edit")) {
397                 // save container's rank
398
saveContainersRank (jParams, engineMap);
399             }
400             // save rights
401
Integer JavaDoc aclID = null;
402             if (engineMap.get ("adminAccess") != null) {
403                 // save container list ACLs
404
if ("ctneditview_rights".equals (engineMap.get ("lastscreen"))) {
405                     String JavaDoc aclfieldname = jParams.getRequest ().getParameter (
406                             "aclfieldname");
407                     logger.debug ("Save container list field ACL : " +
408                             aclfieldname);
409                     // save container list field acl
410
HashMap JavaDoc acls = (HashMap JavaDoc) engineMap.get ("fieldAcls");
411                     if (acls != null) {
412                         aclID = (Integer JavaDoc) acls.get (aclfieldname);
413                         ManageRights.getInstance ().handleActions (jParams, mode,
414                                 engineMap, aclID.intValue ());
415                     }
416                 } else {
417                     //ViewRights.getInstance().handleActions( jParams, mode, engineMap,
418
ManageRights.getInstance ().handleActions (jParams, mode,
419                             engineMap,
420                             theContainerList.getAclID ());
421                 }
422             }
423
424             // save categories
425
ManageCategories.getInstance ().handleActions (jParams, mode,
426                     engineMap,
427                     new ContentContainerListKey (theContainerList.getID ()),
428                     theContainerList.getDefinition (), false);
429
430             flushPageCacheThatDisplayContainerList (jParams, theContainerList);
431
432             // fire event
433
JahiaEvent theEvent = new JahiaEvent (this, jParams,
434                     theContainerList);
435             ServicesRegistry.getInstance ().getJahiaEventService ().
436                     fireSetContainerListProperties (theEvent);
437             if (theScreen.equals ("apply")) {
438                 engineMap.put ("screen",
439                         jParams.getRequest ().getParameter ("lastscreen"));
440                 String JavaDoc lastScreen = (String JavaDoc) engineMap.get ("lastscreen");
441                 if ("ctneditview_rights".equals (lastScreen)) {
442                     ManageRights.getInstance ().handleActions (jParams,
443                             JahiaEngine.LOAD_MODE,
444                             engineMap, aclID.intValue ());
445                 } else if ("rightsMgmt".equals (lastScreen)) {
446                     ManageRights.getInstance ().handleActions (jParams,
447                             JahiaEngine.LOAD_MODE,
448                             engineMap, theContainerList.getAclID ());
449                 }
450             }
451             // #ifdef LOCK
452
else {
453                 if (jParams.settings ().areLocksActivated ()) {
454                     lockRegistry.release (lockKey, jParams.getUser (),
455                             jParams.getSessionID ());
456                 }
457             }
458             // #endif
459
logger.debug ("Container list saved");
460         }
461         // #ifdef LOCK
462
else if (theScreen.equals ("cancel")) {
463             if (jParams.settings ().areLocksActivated ()) {
464                 lockRegistry.release (lockKey, jParams.getUser (),
465                         jParams.getSessionID ());
466                 flushPageCacheThatDisplayContainerList (jParams, theContainerList);
467             }
468         }
469         // #endif
470

471     }
472
473     private void flushPageCacheThatDisplayContainerList (ParamBean jParams,
474                                                          JahiaContainerList theContainerList)
475             throws JahiaException {
476         // Get the cache instance and invalidate the related page entries
477
HtmlCache htmlCache = CacheFactory.getHtmlCache ();
478         if (htmlCache == null)
479             logger.warn ("Could not get the HTML cache instance!!");
480
481         // since we have made modifications concerning this page, let's flush
482
// the content cache for all the users and browsers as well as all
483
// pages that display this containerList...
484
if (theContainerList != null) {
485             Set JavaDoc containerPageRefs = ContentContainerListsXRefManager.
486                     getInstance ().
487                     getAbsoluteContainerListPageIDs (
488                             theContainerList.getID ());
489             if (containerPageRefs != null) {
490                 Iterator JavaDoc pageRefIDs = containerPageRefs.iterator ();
491                 while (pageRefIDs.hasNext ()) {
492                     Integer JavaDoc curPageID = (Integer JavaDoc) pageRefIDs.next ();
493                     if (htmlCache != null)
494                         htmlCache.invalidatePageEntries (curPageID.toString (),jParams.getEntryLoadRequest().getWorkflowState());
495                 }
496             } else {
497                 logger.debug ("Why is cross ref list empty ?");
498             }
499         } else {
500             logger.debug ("Couldn't retrieve parent containerList, why is that ?");
501         }
502
503         // since we updated properties on this container list, let's flush
504
// the cache for the page this container list is on...
505
if (htmlCache != null)
506             htmlCache.invalidatePageEntries (Integer.toString (jParams.getPageID ()),jParams.getEntryLoadRequest().getWorkflowState());
507     }
508
509     /**
510      * inits the engine map
511      * <p/>
512      * The vector "containers" contains all the containers of the container list. The vector
513      * "fieldInfoToDisplay" contains the fields values on which the sort is done. a value in
514      * "fieldInfoToDisplay" correspond to the container at the same index into "containers".
515      *
516      * @param jParams a ParamBean object (with request and response)
517      *
518      * @return a HashMap object containing all the basic values needed by an engine
519      */

520     private HashMap JavaDoc initEngineMap (ParamBean jParams)
521             throws JahiaException,
522             JahiaSessionExpirationException {
523
524         HashMap JavaDoc engineMap = new HashMap JavaDoc ();
525         JahiaContainerList theContainerList = null;
526
527         String JavaDoc theScreen = jParams.getRequest ().getParameter ("screen");
528         String JavaDoc cListIDStr = jParams.getRequest ().getParameter ("clid");
529         int cListID = 0;
530         try {
531             cListID = Integer.parseInt (cListIDStr);
532         } catch (Exception JavaDoc e) {
533             throw new JahiaException ("Error in parameters",
534                     "ContainerListProperties_Engine : error in parameters",
535                     JahiaException.PARAMETER_ERROR,
536                     JahiaException.CRITICAL_SEVERITY);
537         }
538
539         // gets session values
540
//HttpSession theSession = jParams.getRequest().getSession (true);
541
HttpSession JavaDoc theSession = jParams.getSession ();
542
543         if (theScreen != null) {
544             // if no, load the container value from the session
545
engineMap = (HashMap JavaDoc) theSession.getAttribute (
546                     "jahia_session_engineMap");
547
548             ///////////////////////////////////////////////////////////////////////////////////////
549
// FIXME -Fulco-
550
//
551
// This is a quick hack, engineMap should not be null if the session didn't
552
// expired. Maybe there are other cases where the engineMap can be null, I didn't
553
// checked them at all.
554
///////////////////////////////////////////////////////////////////////////////////////
555
if (engineMap == null) {
556                 throw new JahiaSessionExpirationException ();
557             }
558
559             theContainerList = (JahiaContainerList) engineMap.get (
560                     "theContainerList");
561         } else {
562             theScreen = "edit";
563             // init engine map
564
engineMap = new HashMap JavaDoc ();
565             theContainerList = ServicesRegistry.getInstance ().
566                     getJahiaContainersService ().loadContainerList (
567                             cListID, LoadFlags.NOTHING, jParams);
568             engineMap.put ("theContainerList", theContainerList);
569
570             // print out container list properties
571
Properties JavaDoc props = theContainerList.getProperties ();
572             Enumeration JavaDoc enumeration = props.propertyNames ();
573             String JavaDoc p = EMPTY_STRING;
574             while (enumeration.hasMoreElements ()) {
575                 p = (String JavaDoc) enumeration.nextElement ();
576                 logger.debug ("Properties : " + props.getProperty (p));
577             }
578
579             // the ordered list of containers
580
Vector JavaDoc containers = new Vector JavaDoc ();
581             Enumeration JavaDoc containerList = theContainerList.getContainers ();
582             JahiaContainer theContainer = null;
583             // the info displayed to make the difference between containers
584
Vector JavaDoc fieldInfoToDisplay = new Vector JavaDoc ();
585             String JavaDoc fieldInfo = EMPTY_STRING;
586             // the date in millisecond (the vector is empty if the field is not a date)
587
Vector JavaDoc sortInfo4Date = new Vector JavaDoc ();
588             String JavaDoc sortInfo = EMPTY_STRING;
589             int cnt = 0;
590
591             while (containerList.hasMoreElements ()) {
592                 cnt++;
593                 theContainer = (JahiaContainer) containerList.nextElement ();
594                 // let's order the container fields in the exact order in which they are decrared in the template
595
// ( not as in the order in which they are stored in db )
596
theContainer.setLanguageCode (jParams.getEntryLoadRequest ().
597                         getFirstLocale (true).toString ());
598                 theContainer.fieldsStructureCheck (jParams);
599                 containers.add (theContainer);
600                 fieldInfo = getFieldInfoToDisplay (0, theContainer, jParams);
601                 if (fieldInfo != null) {
602                     if (fieldInfo.equals (EMPTY_STRING)) {
603                         fieldInfo = "-- Item " + cnt + " --";
604                     }
605                 } else {
606                     fieldInfo = "-- Item " + cnt + " --";
607                 }
608                 fieldInfoToDisplay.add (fieldInfo);
609
610                 sortInfo = getSortInfo4Date (0, theContainer, jParams);
611                 if (sortInfo != null) {
612                     sortInfo4Date.add (sortInfo);
613                 }
614             }
615
616             JahiaField theField = null;
617             Enumeration JavaDoc fieldsList = null;
618             Vector JavaDoc fields = null;
619
620             if (theContainer == null) {
621                 // no containers in the container list
622
// create an empty container facade
623
ContentPage contentPage =
624                         ContentPage.getPage (theContainerList.getPageID (), false);
625                 JahiaContentContainerFacade contentContainerFacade =
626                         new JahiaContentContainerFacade (0,
627                                 contentPage.getJahiaID (),
628                                 theContainerList.getPageID (),
629                                 theContainerList.getID (),
630                                 theContainerList.getctndefid (),
631                                 //contentPage.getAclID(),
632
0,
633                                 jParams,
634                                 jParams.getSite ().getLanguageSettingsAsLocales (false));
635                 if (contentContainerFacade.getContainers ().hasMoreElements ()) {
636                     theContainer = (JahiaContainer)
637                             contentContainerFacade.getContainers ().
638                             nextElement ();
639                     if (theContainer != null) {
640                         theContainerList.addContainer (theContainer);
641                     }
642                 }
643             }
644
645             if (theContainer != null) {
646                 fieldsList = theContainer.getFields ();
647
648                 fields = new Vector JavaDoc ();
649
650                 while (fieldsList.hasMoreElements ()) {
651                     theField = (JahiaField) fieldsList.nextElement ();
652                     fields.add (theField);
653                 }
654             }
655
656             engineMap.put ("containers", containers);
657             engineMap.put ("fields", fields);
658             engineMap.put ("cursorField", new Integer JavaDoc (0));
659             engineMap.put ("fieldInfoToDisplay", fieldInfoToDisplay);
660             engineMap.put ("containerSelected", new Integer JavaDoc (0));
661
662             // build container list field acl
663
HashMap JavaDoc fieldAcls = buildFieldDefAcls (theContainerList, jParams,
664                     engineMap);
665             engineMap.put ("fieldAcls", fieldAcls);
666         }
667
668         if (theContainerList == null) {
669             throw new JahiaException ("ContainerList not found",
670                     "ContainerListProperties_Engine : ContainerList not found",
671                     JahiaException.PARAMETER_ERROR,
672                     JahiaException.CRITICAL_SEVERITY);
673         }
674
675         Properties JavaDoc extraParams = new Properties JavaDoc ();
676         String JavaDoc containerListName = theContainerList.getDefinition ().getName ();
677         String JavaDoc scrollStr = jParams.getParameter ("ctnscroll_" +
678                 containerListName);
679         if (scrollStr != null) {
680             if (scrollStr.length () > 0) {
681                 extraParams.setProperty ("ctnscroll_" + containerListName,
682                         scrollStr);
683             }
684         }
685         engineMap.put (RENDER_TYPE_PARAM, new Integer JavaDoc (JahiaEngine.RENDERTYPE_FORWARD));
686         engineMap.put (ENGINE_NAME_PARAM, ENGINE_NAME);
687         engineMap.put (ENGINE_URL_PARAM,
688                 jParams.composeEngineUrl (ENGINE_NAME, extraParams,
689                         "&clid=" +
690                 theContainerList.getID ()));
691         theSession.setAttribute ("jahia_session_engineMap", engineMap);
692
693         // sets screen
694
engineMap.put ("screen", theScreen);
695         if (theScreen.equals ("save")) {
696             engineMap.put ("jspSource", "close");
697         } else if (theScreen.equals ("apply")) {
698             engineMap.put ("jspSource", "apply");
699         } else if (theScreen.equals ("cancel")) {
700             engineMap.put ("jspSource", "close");
701         } else {
702             engineMap.put ("jspSource", TEMPLATE_JSP);
703         }
704         /*
705                  // sets screen
706                  engineMap.put( "screen", theScreen );
707                  if (theScreen.equals("cancel")) {
708                      engineMap.put( "jspSource", "close" );
709                  } else if (theScreen.equals("save")) {
710                      engineMap.put( "jspSource", "close" );
711                  } else if (theScreen.equals ("apply")) {
712                      String lastScreen = (String)engineMap.get("lastscreen");
713                      if (!"ctneditview_rights".equals(lastScreen)) {
714                          engineMap.put( "jspSource", "apply" );
715                      }
716                  } else {
717                      engineMap.put( "jspSource", TEMPLATE_JSP );
718                  }
719          */

720         engineMap.put ("doAddEditViewRight", new Boolean JavaDoc (true));
721
722         if (theContainerList.getID () != 0) {
723             engineMap.put ("enableCategories", new Boolean JavaDoc (true));
724         }
725
726         // sets engineMap for JSPs
727
jParams.getRequest ().setAttribute ("engineTitle",
728                 "Container List Settings");
729         jParams.getRequest ().setAttribute ("org.jahia.engines.EngineHashMap",
730                 engineMap);
731
732         return engineMap;
733     }
734
735     /**
736      * loads container list data for the JSP file
737      *
738      * @param jParams a ParamBean object (with request and response)
739      * @param engineMap then engine map, to be forwarded to the JSP file
740      */

741     private void loadContainerListData (ParamBean jParams, HashMap JavaDoc engineMap)
742             // throws JahiaException
743
{
744         // do nothin'... for now
745
}
746
747     /**
748      * gets container list POST form data from the JSP file
749      * <p/>
750      * The vector "containers" contains all the containers of the container list. The vector
751      * "fieldInfoToDisplay" contains the fields values on which the sort is done. a value in
752      * "fieldInfoToDisplay" correspond to the container at the same index into "containers".
753      *
754      * @param jParams a ParamBean object (with request and response)
755      * @param engineMap then engine map, to be forwarded to the JSP file
756      *
757      * @return true if everything went okay, false if not
758      */

759     private boolean updateContainerListData (ParamBean jParams,
760                                              HashMap JavaDoc engineMap)
761             throws JahiaException {
762         boolean okay = true;
763         //FIXME: set JahiaExceptions
764

765         //JahiaContainerList theContainerList = (JahiaContainerList)engineMap.get( "theContainerList" );
766

767         String JavaDoc updMode = jParams.getRequest ().getParameter ("updMode");
768         Vector JavaDoc containers = (Vector JavaDoc) engineMap.get ("containers");
769         Vector JavaDoc fieldInfoToDisplay = (Vector JavaDoc) engineMap.get ("fieldInfoToDisplay");
770         Vector JavaDoc sortInfo4Date = (Vector JavaDoc) engineMap.get ("sortInfo4Date");
771
772         if (updMode != null) {
773             // **** change cursor field ****
774
if (updMode.equals ("cursor")) {
775                 String JavaDoc curFieldStr = jParams.getRequest ().getParameter (
776                         "cursorField");
777                 int curField = 0;
778                 if (curFieldStr != null) {
779                     try {
780                         curField = Integer.parseInt (curFieldStr);
781                     } catch (NumberFormatException JavaDoc nfe) {
782                         ;
783                     }
784                 }
785
786                 fieldInfoToDisplay = new Vector JavaDoc ();
787                 String JavaDoc fieldInfo = EMPTY_STRING;
788                 sortInfo4Date = new Vector JavaDoc ();
789                 String JavaDoc sortInfo = EMPTY_STRING;
790
791                 for (int i = 0; i < containers.size (); i++) {
792                     fieldInfo = getFieldInfoToDisplay (curField,
793                             (JahiaContainer) containers.get (i), jParams);
794                     if (fieldInfo.equals (EMPTY_STRING)) {
795                         fieldInfo = "-- Item " + (i + 1) + " --";
796                     }
797                     fieldInfoToDisplay.add (fieldInfo);
798
799                     sortInfo = getSortInfo4Date (curField,
800                             (JahiaContainer)
801                             containers.get (i), jParams);
802                     if (sortInfo != null) {
803                         sortInfo4Date.add (sortInfo);
804                     }
805                 }
806
807                 engineMap.put ("fieldInfoToDisplay", fieldInfoToDisplay);
808                 engineMap.put ("sortInfo4Date", sortInfo4Date);
809                 engineMap.put ("cursorField", new Integer JavaDoc (curField));
810
811             }
812             // **** end change cursor field ****
813

814             // ++++ manual ranking ++++
815
/*
816                          else if (updMode.equals("manual"))
817                          {
818                  String containerNumberStr = jParams.getRequest().getParameter("manRank");
819                 int containerNumber = 0;
820                 if (containerNumberStr != null)
821                 {
822                     try {
823                         containerNumber = Integer.parseInt(containerNumberStr);
824                     } catch (NumberFormatException nfe) {
825                         ;
826                     }
827                 }
828                 String move = jParams.getRequest().getParameter("move");
829                 JahiaContainer c = null;
830                 String str = EMPTY_STRING;
831                 if (move.equals("top"))
832                 {
833                     c = (JahiaContainer)containers.remove(containerNumber);
834                     containers.add(0,c);
835                     str = (String)fieldInfoToDisplay.remove(containerNumber);
836                     fieldInfoToDisplay.add(0,str);
837                     engineMap.put("containerSelected", new Integer(0));
838                 }
839                 else if (move.equals("up"))
840                 {
841                     if (containerNumber >0)
842                     {
843                         c = (JahiaContainer)containers.get(containerNumber);
844                  containers.set(containerNumber,containers.get(containerNumber-1));
845                         containers.set(containerNumber-1,c);
846                         str = (String)fieldInfoToDisplay.get(containerNumber);
847                         fieldInfoToDisplay.set(containerNumber,fieldInfoToDisplay.get(containerNumber-1));
848                         fieldInfoToDisplay.set(containerNumber-1,str);
849                  engineMap.put("containerSelected", new Integer(containerNumber-1));
850                     }
851                 }
852                 else if (move.equals("down"))
853                 {
854                     if (containerNumber < containers.size()-1)
855                     {
856                         c = (JahiaContainer)containers.get(containerNumber);
857                  containers.set(containerNumber,containers.get(containerNumber+1));
858                         containers.set(containerNumber+1,c);
859                         str = (String)fieldInfoToDisplay.get(containerNumber);
860                         fieldInfoToDisplay.set(containerNumber,fieldInfoToDisplay.get(containerNumber+1));
861                         fieldInfoToDisplay.set(containerNumber+1,str);
862                  engineMap.put("containerSelected", new Integer(containerNumber+1));
863                     }
864                 }
865                 else // bottom
866                 {
867                     c = (JahiaContainer)containers.remove(containerNumber);
868                     containers.add(c);
869                     str = (String)fieldInfoToDisplay.remove(containerNumber);
870                     fieldInfoToDisplay.add(str);
871                  engineMap.put("containerSelected", new Integer(containers.size()-1));
872                 }
873                 engineMap.put("fieldInfoToDisplay", fieldInfoToDisplay);
874                 engineMap.put("containers", containers);
875                          }
876                          // ++++ end manual ranking ++++
877              */

878
879             // **** automatic ranking ****
880
else if (updMode.equals ("automatic")) {
881                 engineMap.put ("containerSelected", new Integer JavaDoc (0));
882                 String JavaDoc containerSort = jParams.getRequest ().getParameter (
883                         "autRank");
884                 engineMap.put ("automatic", containerSort);
885                 shell_sort (jParams, engineMap, containerSort);
886             }
887             // ****end automatic ranking ****
888
}
889
890         return okay;
891     }
892
893     /**
894      * save the rank of each container of the container list
895      *
896      * @param jParams a ParamBean object (with request and response)
897      * @param engineMap then engine map, to be forwarded to the JSP file
898      */

899     private void saveContainersRank (ParamBean jParams, HashMap JavaDoc engineMap)
900             throws JahiaException {
901         Vector JavaDoc containers_beforeSort = (Vector JavaDoc) engineMap.get ("containers");
902         Vector JavaDoc containers = new Vector JavaDoc ();
903
904         String JavaDoc[] manRank = jParams.getRequest ().getParameterValues ("manRank");
905         if (manRank != null) {
906             int num = 0;
907             for (int j = 0; j < manRank.length; j++) {
908                 num = Integer.parseInt (manRank[j]);
909                 //System.out.println("####### Debug save CList: "+num);
910
containers.add (containers_beforeSort.get (num));
911             }
912         }
913         int counter = containers.size ();
914         JahiaContainer c;
915
916         // rank are save with negative number, because new containers have a rank equal to 0.
917
// then new containers will appear at the end of the container list.
918
for (int i = 0; i < containers.size (); i++) {
919             c = (JahiaContainer) containers.get (i);
920             c.setRank (counter * (-1));
921             ServicesRegistry.getInstance ().getJahiaContainersService ().
922                     saveContainerInfo (c, 0, 0, jParams);
923             counter--;
924         }
925
926     }
927
928     /**
929      * get the fieldInfo corresponding to the field "cursorField" of the container
930      *
931      * @param cursorField the number of the field into the container
932      * @param theContainer the container in which get the fieldInfo
933      */

934     private String JavaDoc getFieldInfoToDisplay (int cursorField,
935                                           JahiaContainer theContainer,
936                                           ParamBean jParams)
937             throws JahiaException {
938         String JavaDoc fieldInfo = EMPTY_STRING;
939         int counter = 0;
940
941         Enumeration JavaDoc fList = theContainer.getFields ();
942
943         while (fList.hasMoreElements ()) {
944             JahiaField f = (JahiaField) fList.nextElement ();
945             f = ServicesRegistry.getInstance ().
946                     getJahiaFieldService ().loadField (f.getID (), LoadFlags.ALL,
947                             jParams);
948
949             if (f != null && (counter == cursorField)) {
950                 fieldInfo = f.getFieldContent4Ranking ();
951
952                 /*
953                                  int fieldType = f.getType();
954                                  switch (fieldType)
955                                  {
956                     case(3): String str = f.getValue();
957                              str = JahiaTools.html2text(str);
958                              if (str.length() > 30)
959                              {
960                                 fieldInfo = str.substring(0,30) +">";
961                              }
962                              else
963                              {
964                                 fieldInfo = str;
965                              }
966                              str = JahiaTools.text2html(str);
967                              break;
968                     case(5): JahiaPage page = (JahiaPage)f.getObject();
969                              if (page != null)
970                              {
971                                 fieldInfo = page.getTitle();
972                              }
973                              else
974                              {
975                                 fieldInfo = f.getValue();
976                              }
977                              break;
978                     case(6):
979                     case(7):
980                     case(8):
981                      case(9): JahiaFileField fle = (JahiaFileField)f.getObject();
982                              if (fle != null)
983                              {
984                                 fieldInfo = fle.getFileFieldTitle();
985                              }
986                              else
987                              {
988                                 fieldInfo = f.getValue();
989                              }
990                              break;
991                     case(10): String appIDStr = (String)f.getObject();
992                               int appID = 0;
993                               if (appIDStr != null)
994                               {
995                                 try {
996                                     appID = Integer.parseInt(appIDStr);
997                                 } catch (NumberFormatException nfe) {
998                                     ;
999                                 }
1000                              }
1001                     ApplicationBean app = ServicesRegistry.getInstance().
1002                     getJahiaApplicationsManagerService().getApplication(appID);
1003                              if (app != null)
1004                              {
1005                                fieldInfo = app.getName();
1006                              }
1007                              else
1008                              {
1009                                fieldInfo = f.getValue();
1010                              }
1011                              break;
1012                    default: fieldInfo = f.getValue();
1013                             break;
1014                                 }
1015                 */

1016            }
1017            counter++;
1018        }
1019
1020        return fieldInfo;
1021    }
1022
1023    /**
1024     * get the date in millisecond
1025     *
1026     * @param cursorField the number of the field into the container
1027     * @param theContainer the container in which get the fieldInfo
1028     */

1029    private String JavaDoc getSortInfo4Date (int cursorField,
1030                                     JahiaContainer theContainer,
1031                                     ParamBean jParams)
1032            throws JahiaException {
1033        String JavaDoc sortInfo = null;
1034        int counter = 0;
1035
1036        Enumeration JavaDoc fList = theContainer.getFields ();
1037        while (fList.hasMoreElements ()) {
1038            JahiaField f = (JahiaField) fList.nextElement ();
1039            //f = ServicesRegistry.getInstance().
1040
//getJahiaFieldService().loadField( f.getID(), LoadFlags.ALL, jParams );
1041

1042            if (counter == cursorField) {
1043                if (f.getType () == 4) {
1044                    sortInfo = (String JavaDoc) f.getObject ();
1045                }
1046            }
1047            counter++;
1048        }
1049
1050        return sortInfo;
1051    }
1052
1053    /**
1054     * sort the containers and the fieldInfoToDisplay vector
1055     * <p/>
1056     * The vector "containers" contains all the containers of the container list. The vector
1057     * "fieldInfoToDisplay" contains the fields values on which the sort is done. a value in
1058     * "fieldInfoToDisplay" correspond to the container at the same index into "containers".
1059     *
1060     * @param jParams a ParamBean object (with request and response)
1061     * @param engineMap then engine map, to be forwarded to the JSP file
1062     * @param containerSort How to sort the containers (alphabetically or order of insertion,
1063     * ascending or descending)
1064     */

1065    private void shell_sort (ParamBean jParams, HashMap JavaDoc engineMap,
1066                             String JavaDoc containerSort)
1067            throws JahiaException {
1068        Vector JavaDoc containers = (Vector JavaDoc) engineMap.get ("containers");
1069        Vector JavaDoc fieldInfoToDisplay = (Vector JavaDoc) engineMap.get ("fieldInfoToDisplay");
1070        Vector JavaDoc sortInfo4Date = (Vector JavaDoc) engineMap.get ("sortInfo4Date");
1071
1072        int n = containers.size ();
1073        int incr;
1074        int j;
1075        JahiaContainer c = null;
1076        String JavaDoc str = EMPTY_STRING;
1077        boolean flag = false;
1078
1079        for (incr = n / 2; incr > 0; incr = incr / 2) {
1080            for (int i = incr; i < n; i++) {
1081                c = (JahiaContainer) containers.get (i);
1082                str = (String JavaDoc) fieldInfoToDisplay.get (i);
1083                String JavaDoc str2 = EMPTY_STRING;
1084                String JavaDoc str4Test = str;
1085                String JavaDoc str4Test2 = EMPTY_STRING;
1086                if (sortInfo4Date != null && !sortInfo4Date.isEmpty ()) {
1087                    str2 = (String JavaDoc) sortInfo4Date.get (i);
1088                    str4Test = str2;
1089                    //System.out.println("sort date "+str+" : "+str2);
1090
}
1091
1092                for (j = i; j >= incr; j = j - incr) {
1093                    if (containerSort.equals ("insertAsc")) {
1094                        if (c.getID () <
1095                                ((JahiaContainer) containers.get (j - incr)).getID ()) {
1096                            flag = true;
1097                        } else {
1098                            flag = false;
1099                        }
1100                    } else if (containerSort.equals ("insertDesc")) {
1101                        if (c.getID () >=
1102                                ((JahiaContainer) containers.get (j - incr)).getID ()) {
1103                            flag = true;
1104                        } else {
1105                            flag = false;
1106                        }
1107                    } else if (containerSort.equals ("alphAsc")) {
1108                        str4Test2 = (String JavaDoc) fieldInfoToDisplay.get (j - incr);
1109                        if (sortInfo4Date != null && !sortInfo4Date.isEmpty ()) {
1110                            str4Test2 = (String JavaDoc) sortInfo4Date.get (j - incr);
1111                        }
1112
1113                        try {
1114                            Double JavaDoc d1 = new Double JavaDoc (str4Test);
1115                            Double JavaDoc d2 = new Double JavaDoc (str4Test2);
1116
1117                            int comp2 = d1.compareTo (d2);
1118                            if (comp2 < 0) {
1119                                flag = true;
1120                            } else {
1121                                flag = false;
1122                            }
1123                        } catch (NumberFormatException JavaDoc e) {
1124                            String JavaDoc value = (String JavaDoc) fieldInfoToDisplay.get (j -
1125                                    incr);
1126                            try {
1127                                str = (new RE ("<(.*?)>")).subst (str, EMPTY_STRING);
1128                                value = (new RE ("<(.*?)>")).subst (value, EMPTY_STRING);
1129                            } catch (RESyntaxException re) {
1130                                logger.debug (re);
1131                            } catch (Throwable JavaDoc t) {
1132                                logger.debug (t);
1133                            }
1134
1135                            int comp = str.compareToIgnoreCase (value);
1136
1137                            if (comp < 0) {
1138                                flag = true;
1139                            } else {
1140                                flag = false;
1141                            }
1142                        }
1143
1144                    } else if (containerSort.equals ("alphDesc")) {
1145                        str4Test2 = (String JavaDoc) fieldInfoToDisplay.get (j - incr);
1146                        if (sortInfo4Date != null && !sortInfo4Date.isEmpty ()) {
1147                            str4Test2 = (String JavaDoc) sortInfo4Date.get (j - incr);
1148                        }
1149
1150                        try {
1151                            Double JavaDoc d1 = new Double JavaDoc (str4Test);
1152                            Double JavaDoc d2 = new Double JavaDoc (str4Test2);
1153
1154                            int comp2 = d1.compareTo (d2);
1155                            if (comp2 >= 0) {
1156                                flag = true;
1157                            } else {
1158                                flag = false;
1159                            }
1160                        } catch (NumberFormatException JavaDoc e) {
1161                            int comp = str.compareToIgnoreCase ((String JavaDoc)
1162                                    fieldInfoToDisplay.get (j - incr));
1163                            if (comp >= 0) {
1164                                flag = true;
1165                            } else {
1166                                flag = false;
1167                            }
1168                        }
1169
1170                    }
1171
1172                    if (flag) {
1173
1174                        containers.set (j, containers.get (j - incr));
1175                        fieldInfoToDisplay.set (j,
1176                                fieldInfoToDisplay.get (j - incr));
1177                        if (sortInfo4Date != null && !sortInfo4Date.isEmpty ()) {
1178                            sortInfo4Date.set (j, sortInfo4Date.get (j - incr));
1179                        }
1180                    } else {
1181                        break;
1182                    }
1183                }
1184                containers.set (j, c);
1185                fieldInfoToDisplay.set (j, str);
1186                if (sortInfo4Date != null && !sortInfo4Date.isEmpty ()) {
1187                    sortInfo4Date.set (j, str2);
1188                }
1189            }
1190        }
1191        engineMap.put ("fieldInfoToDisplay", fieldInfoToDisplay);
1192        engineMap.put ("sortInfo4Date", sortInfo4Date);
1193        engineMap.put ("containers", containers);
1194
1195    }
1196
1197    // Khue Nguyen
1198
/**
1199     * composes the hashmap that contains the pair (String fieldDefName, Integer aclID)
1200     *
1201     * @param cList the container list
1202     * @param jParams the parambean that contains reference to the page
1203     * @param engineMap needed to store the first field def name as "fieldAclDefaultField"
1204     * attribute
1205     *
1206     * @return HashMap
1207     */

1208    private HashMap JavaDoc buildFieldDefAcls (JahiaContainerList cList,
1209                                       ParamBean jParams,
1210                                       HashMap JavaDoc engineMap)
1211            throws JahiaException {
1212        HashMap JavaDoc hash = new HashMap JavaDoc ();
1213
1214        if (cList == null || jParams.getPage () == null)
1215            return hash;
1216
1217        JahiaContainer theContainer = null;
1218
1219        Enumeration JavaDoc enumeration = cList.getContainers ();
1220        if (enumeration.hasMoreElements ())
1221            theContainer = (JahiaContainer) enumeration.nextElement (); // get the first available ctn.
1222

1223        if (theContainer == null)
1224            return hash;
1225
1226        String JavaDoc prop = null;
1227        boolean done = false;
1228
1229        JahiaField aField = null;
1230        JahiaFieldDefinition theDef = null;
1231
1232        Enumeration JavaDoc fList = theContainer.getFields ();
1233        while (fList.hasMoreElements ()) {
1234            aField = (JahiaField) fList.nextElement ();
1235
1236            theDef = aField.getDefinition ();
1237            if (theDef != null) {
1238                prop = cList.getProperty ("view_field_acl_" + theDef.getName ());
1239                if (prop != null) {
1240                    try {
1241                        int aclID = Integer.parseInt (prop);
1242                        hash.put (theDef.getName (), new Integer JavaDoc (aclID));
1243                        if (!done) {
1244                            engineMap.put ("fieldAclDefaultField",
1245                                    theDef.getName ());
1246                            done = true;
1247                        }
1248                    } catch (Throwable JavaDoc t) {
1249                        logger.debug (" requested acl ( view_field_acl_" +
1250                                theDef.getName () + "), fail ");
1251                    }
1252                } else {
1253                    // create the acl, because field declaration can change in template
1254
JahiaBaseACL newAcl = null;
1255                    newAcl = new JahiaBaseACL ();
1256                    newAcl.create (cList.getAclID ());
1257                    cList.setProperty ("view_field_acl_" + theDef.getName (),
1258                            String.valueOf (newAcl.getID ()));
1259                    ServicesRegistry.getInstance ().
1260                            getJahiaContainersService ().saveContainerListInfo (cList,
1261                                    jParams.getPage ().getAclID ());
1262
1263                    hash.put (theDef.getName (), new Integer JavaDoc (newAcl.getID ()));
1264                    if (!done) {
1265                        engineMap.put ("fieldAclDefaultField", theDef.getName ());
1266                        done = true;
1267                    }
1268                }
1269            }
1270        }
1271
1272        logger.debug ("Returned hashMap");
1273        theContainer = null;
1274        return hash;
1275    }
1276}
1277
Popular Tags