KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jahia > services > fields > JahiaFieldBaseService


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  *
14  * ----- BEGIN LICENSE BLOCK -----
15  * Version: JCSL 1.0
16  *
17  * The contents of this file are subject to the Jahia Community Source License
18  * 1.0 or later (the "License"); you may not use this file except in
19  * compliance with the License. You may obtain a copy of the License at
20  * http://www.jahia.org/license
21  *
22  * Software distributed under the License is distributed on an "AS IS" basis,
23  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
24  * for the rights, obligations and limitations governing use of the contents
25  * of the file. The Original and Upgraded Code is the Jahia CMS and Portal
26  * Server. The developer of the Original and Upgraded Code is JAHIA Ltd. JAHIA
27  * Ltd. owns the copyrights in the portions it created. All Rights Reserved.
28  *
29  * The Shared Modifications are Jahia View Helper.
30  *
31  * The Developer of the Shared Modifications is Jahia Solution S�rl.
32  * Portions created by the Initial Developer are Copyright (C) 2002 by the
33  * Initial Developer. All Rights Reserved.
34  *
35  * Contributor(s):
36  * 31-OCT-2000, Xo3 SA, Eric Vassalli : Initial version
37  * 05-JAN-2001, Xo3 SA, David Jilly
38  * 08-JAN-2001, Xo3 SA, Eric Vassalli
39  * 09-AUG-2003, Jahia Solutions Sarl, Fulco Houkes
40  *
41  * ----- END LICENSE BLOCK -----
42  */

43
44
45 package org.jahia.services.fields;
46
47 import java.io.File JavaDoc;
48 import java.io.IOException JavaDoc;
49 import java.lang.reflect.Constructor JavaDoc;
50 import java.lang.reflect.InvocationTargetException JavaDoc;
51 import java.util.Enumeration JavaDoc;
52 import java.util.Hashtable JavaDoc;
53 import java.util.Map JavaDoc;
54 import java.util.Set JavaDoc;
55 import java.util.SortedSet JavaDoc;
56 import java.util.TreeSet JavaDoc;
57 import java.util.Vector JavaDoc;
58
59 import org.apache.log4j.Logger;
60 import org.jahia.bin.Jahia;
61 import org.jahia.data.ConnectionTypes;
62 import org.jahia.data.JahiaDOMObject;
63 import org.jahia.data.JahiaData;
64 import org.jahia.data.containers.JahiaContainer;
65 import org.jahia.data.containers.JahiaContainerList;
66 import org.jahia.data.events.JahiaEvent;
67 import org.jahia.data.fields.FieldTypes;
68 import org.jahia.data.fields.JahiaField;
69 import org.jahia.data.fields.JahiaFieldDefinition;
70 import org.jahia.data.fields.JahiaFieldSet;
71 import org.jahia.data.fields.LoadFlags;
72 import org.jahia.exceptions.JahiaException;
73 import org.jahia.exceptions.JahiaInitializationException;
74 import org.jahia.params.ParamBean;
75 import org.jahia.registries.JahiaFieldDefinitionsRegistry;
76 import org.jahia.registries.ServicesRegistry;
77 import org.jahia.services.acl.JahiaBaseACL;
78 import org.jahia.services.containers.FieldsChangeEventListener;
79 import org.jahia.services.containers.JahiaContainersService;
80 import org.jahia.services.files.JahiaTextFileService;
81 import org.jahia.services.pages.ContentPage;
82 import org.jahia.services.usermanager.JahiaUser;
83 import org.jahia.services.version.ActivationTestResults;
84 import org.jahia.services.version.ContentObjectEntryState;
85 import org.jahia.services.version.EntryLoadRequest;
86 import org.jahia.services.version.JahiaSaveVersion;
87 import org.jahia.services.version.StateModificationContext;
88 import org.jahia.settings.SettingsBean;
89 import org.jahia.utils.xml.XMLSerializationOptions;
90 import org.jahia.utils.xml.XmlWriter;
91
92
93 public class JahiaFieldBaseService extends JahiaFieldService {
94
95     private static Logger logger = Logger.getLogger (JahiaFieldBaseService.class);
96
97     /** the unique instance of this class */
98     private static JahiaFieldBaseService instance;
99
100     private static SettingsBean jSettings;
101
102     private JahiaFieldsDB fieldsDB;
103     private JahiaFieldDefinitionsDB f_defs;
104     private JahiaFieldUtilsDB f_utils;
105
106     private Hashtable JavaDoc fieldClassNames;
107     private Hashtable JavaDoc fieldClassConstructor = new Hashtable JavaDoc ();
108
109     // the Fields cache name.
110
public static final String JavaDoc FIELD_CACHE = "FieldCache";
111     //private Cache cacheFields;
112

113
114     /**
115      * Defaulf constructor, creates a new <code>JahiaFieldBaseService</code> instance.
116      */

117     protected JahiaFieldBaseService () {
118         logger.debug ("***** Starting up the Field Services *****");
119     }
120
121
122     /**
123      * Return the unique instance of this class
124      *
125      * @return the unique instance of this class
126      */

127     public static synchronized JahiaFieldBaseService getInstance () {
128
129         if (instance == null) {
130             instance = new JahiaFieldBaseService ();
131         }
132         return instance;
133     }
134
135
136     /**
137      * Initialize the service
138      *
139      * @param settings Settings to let the sevice where to save files, i.e.
140      */

141     public void init (SettingsBean settings)
142             throws JahiaInitializationException {
143         JahiaFieldBaseService.jSettings = settings;
144
145         fieldsDB = new JahiaFieldsDB (JahiaFieldBaseService.jSettings);
146         f_defs = new JahiaFieldDefinitionsDB ();
147         f_utils = new JahiaFieldUtilsDB ();
148
149         // get the hashtable which give the class name
150
// which correspond to the field type.
151
fieldClassNames = FieldTypes.getInstance ().getFieldClassNames ();
152
153         //cacheFields = CacheFactory.createCache (FIELD_CACHE);
154

155         // create field definitions directory for flat files
156
createFileDefinitionRepository ();
157     }
158
159
160     /**
161      * create a JahiaField.
162      * The only method to instanciate a new JahiaField
163      * It call the constructor corresponding to the field type.
164      * This method must NOT be called directly,
165      * but only by JahiaFieldSet.declareField()
166      * and JahiaFieldDB.db_load_field().
167      */

168     public JahiaField createJahiaField (int ID,
169                                         int jahiaID,
170                                         int pageID,
171                                         int ctnid,
172                                         int fieldDefID,
173                                         int fieldType,
174                                         int connectType,
175                                         String JavaDoc fieldValue,
176                                         int rank,
177                                         int aclID,
178                                         int versionID,
179                                         int versionStatus,
180                                         String JavaDoc languageCode)
181             throws JahiaException {
182         JahiaField theField;
183
184         fieldValue = checkFieldEnumerationValues (fieldValue);
185
186         try {
187
188             logger.debug ("fieldType: " + fieldType + " class: "
189                     + fieldClassNames.get (new Integer JavaDoc (fieldType)));
190
191             // get the constructor by its name
192
// the name come from the hashtable
193
Integer JavaDoc fieldTypeInt = new Integer JavaDoc (fieldType);
194             Constructor JavaDoc thisConstructor = null;
195             if (fieldClassConstructor.containsKey (fieldTypeInt)) {
196                 thisConstructor = (Constructor JavaDoc) fieldClassConstructor.get (fieldTypeInt);
197             } else {
198                 // define the types of the parameter of the constructor
199
Class JavaDoc theParams[] = {Integer JavaDoc.class,
200                                      Integer JavaDoc.class,
201                                      Integer JavaDoc.class,
202                                      Integer JavaDoc.class,
203                                      Integer JavaDoc.class,
204                                      Integer JavaDoc.class,
205                                      Integer JavaDoc.class,
206                                      String JavaDoc.class,
207                                      Integer JavaDoc.class,
208                                      Integer JavaDoc.class,
209                                      Integer JavaDoc.class,
210                                      Integer JavaDoc.class,
211                                      String JavaDoc.class};
212
213                 String JavaDoc fieldClassName = (String JavaDoc) fieldClassNames
214                         .get(new Integer JavaDoc(fieldType));
215                 if (fieldClassName != null) {
216                     thisConstructor = Class.forName(fieldClassName)
217                             .getDeclaredConstructor(theParams);
218                     fieldClassConstructor.put(fieldTypeInt, thisConstructor);
219                 } else {
220                     throw new JahiaException("Error accessing field",
221                             "Couldn't find field class name for type "
222                                     + fieldType + " pageID=" + pageID
223                                     + " fieldDefID=" + fieldDefID + " ctnID="
224                                     + ctnid, JahiaException.PERSISTENCE_ERROR,
225                             JahiaException.ERROR_SEVERITY);
226                 }
227             }
228
229
230             // the parameter values of the constructor
231
Object JavaDoc args[] = {new Integer JavaDoc (ID), new Integer JavaDoc (jahiaID),
232                              new Integer JavaDoc (pageID), new Integer JavaDoc (ctnid),
233                              new Integer JavaDoc (fieldDefID),
234                              new Integer JavaDoc (fieldType),
235                              new Integer JavaDoc (connectType), fieldValue,
236                              new Integer JavaDoc (rank), new Integer JavaDoc (aclID),
237                              new Integer JavaDoc (versionID), new Integer JavaDoc (versionStatus),
238                              new String JavaDoc (languageCode)};
239
240
241             // call the constructor
242
theField = (JahiaField) thisConstructor.newInstance (args);
243
244         } catch (ClassNotFoundException JavaDoc cnfe) {
245             logger.debug ("exception (class nf) " + cnfe.toString (), cnfe);
246             throw new JahiaException ("JahiaFieldBaseService:createJahiaField",
247                     "Class not found!",
248                     JahiaException.PAGE_ERROR, JahiaException.CRITICAL_SEVERITY, cnfe);
249
250         } catch (NoSuchMethodException JavaDoc nsme) {
251             logger.debug ("createJahiaField: (method nf) " + nsme.toString (), nsme);
252             throw new JahiaException ("JahiaFieldBaseService:createJahiaField",
253                     "Method not found!",
254                     JahiaException.PAGE_ERROR, JahiaException.CRITICAL_SEVERITY, nsme);
255
256         } catch (IllegalAccessException JavaDoc iae) {
257             logger.debug ("createJahiaField: (illegal access) " + iae.toString (), iae);
258             throw new JahiaException ("JahiaFieldBaseService:createJahiaField",
259                     "Illegal access",
260                     JahiaException.PAGE_ERROR, JahiaException.CRITICAL_SEVERITY, iae);
261
262         } catch (InvocationTargetException JavaDoc ite) {
263             logger.debug ("createJahiaField: (invocation) " + ite.toString (), ite);
264             throw new JahiaException ("JahiaFieldBaseService:createJahiaField",
265                     "InvocationTarget exception",
266                     JahiaException.PAGE_ERROR, JahiaException.CRITICAL_SEVERITY, ite);
267
268         } catch (InstantiationException JavaDoc ie) {
269             logger.debug ("createJahiaField: (instantiation) " + ie.toString (), ie);
270             throw new JahiaException ("JahiaFieldBaseService:createJahiaField",
271                     "Instantiation exception",
272                     JahiaException.PAGE_ERROR, JahiaException.CRITICAL_SEVERITY, ie);
273         }
274
275         // return the new JahiaField
276
return theField;
277     }
278
279
280     /**
281      * Create a new field
282      *
283      * @param ID the field identification
284      * @param jahiaID
285      * @param pageID the related page identification
286      * @param ctnid the related container identification
287      * @param fieldDefID
288      * @param fieldType
289      * @param connectType
290      * @param fieldValue the field value
291      * @param rank the field position
292      * @param aclID the ACL identification
293      *
294      * @return Returns a new <code>JahiaField</code> instance, initialized with the
295      * specified arguments.
296      *
297      * @throws JahiaException when a creation failure occured
298      */

299     public JahiaField createJahiaField (int ID, int jahiaID, int pageID, int ctnid,
300                                         int fieldDefID, int fieldType, int connectType,
301                                         String JavaDoc fieldValue, int rank, int aclID)
302             throws JahiaException {
303         fieldValue = checkFieldEnumerationValues (fieldValue);
304
305         return createJahiaField (ID, jahiaID, pageID, ctnid, fieldDefID, fieldType,
306                 connectType, fieldValue, rank, aclID, 0,
307                 EntryLoadRequest.STAGING_WORKFLOW_STATE,
308                 Jahia.getSettings ().getDefaultLanguageCode ());
309     }
310
311
312     /**
313      * clone page field
314      *
315      * @param fieldID the field to clone.
316      * @param newPageID The Id of the new page to which the cloned field must
317      * belong to.
318      */

319     public synchronized void cloneField (int fieldID, int newPageID, int parentAclID,
320                                          ParamBean jParams)
321             throws JahiaException {
322         // get the field object
323
JahiaField theField = loadField (fieldID, LoadFlags.NOTHING, jParams);
324
325         // clone field
326
cloneField (theField, 0, newPageID, parentAclID, false);
327     }
328
329
330     /**
331      * clone page field
332      *
333      * @param theField the field to clone.
334      * @param newctnid the id of the container which contains the field
335      * equal 0 if the field is in a page.
336      * @param newPageID The Id of the new page to which the cloned field must
337      * belong to.
338      */

339     public synchronized JahiaField cloneField (JahiaField theField, int newctnid,
340                                                int newPageID, int parentAclID,
341                                                boolean childrenCloned)
342             throws JahiaException {
343         // get the field object
344
logger.debug ("cloneField(): begin");
345         theField = loadField (theField.getID (), LoadFlags.ALL, null);
346         if (theField == null) {
347             throw new JahiaException ("Could not clone field.",
348                     "Could not get the JahiaField object.",
349                     JahiaException.PAGE_ERROR, JahiaException.CRITICAL_SEVERITY);
350         }
351
352
353         //cloneACl
354
JahiaBaseACL aclObj = theField.getACL();
355         if (aclObj == null) {
356             throw new JahiaException ("Could not clone container.",
357                     "Could not get JahiaBaseACL object.",
358                     JahiaException.PAGE_ERROR, JahiaException.CRITICAL_SEVERITY);
359         }
360
361         JahiaBaseACL clonedACL = (JahiaBaseACL) aclObj.clone ();
362         if (clonedACL == null) {
363             throw new JahiaException ("Could not clone container.",
364                     "Could not clone acl.",
365                     JahiaException.PAGE_ERROR, JahiaException.CRITICAL_SEVERITY);
366         }
367         clonedACL.setParentID (parentAclID);
368
369
370         // clone field
371
//JahiaField clonedField = new JahiaField(0, theField.getJahiaID(), newPageID, newctnid,
372
// theField.getFieldDefID(), theField.getType(),
373
// theField.getConnectType(), theField.getValue(),
374
// theField.getRank(), clonedACL.getID() );
375

376         JahiaField clonedField = null;
377
378         clonedField =
379                 theField.cloneField (newctnid, newPageID, clonedACL.getID (), childrenCloned);
380
381         /*
382         if (theField.getType() == FieldTypes.DATE)
383         {
384             clonedField = theField.cloneField(newctnid, newPageID, clonedACL.getID());
385         } else
386         {
387
388         clonedField = createJahiaField(0, theField.getJahiaID(),
389                                  newPageID, newctnid,
390                                  theField.getFieldDefID(), theField.getType(),
391                                  theField.getConnectType(),
392                                  theField.getValue(), theField.getRank(),
393                                  clonedACL.getID() );
394
395         logger.debug("cloneField(): value = "+theField.getValue());
396         if (clonedField == null)
397         {
398             throw new JahiaException ("Could not clone field.",
399                 "Could not instanciate a new JahiaField object.",
400                 JahiaException.PAGE_ERROR, JahiaException.CRITICAL);
401         }
402
403         clonedField.setRawValue(theField.getRawValue());
404         clonedField.setObject( theField.getObject() );
405         clonedField.setProperties( (Hashtable)(theField.getProperties()).clone() );
406         }
407         */

408
409         // saves field
410
logger.debug ("cloneField(): call saveField");
411
412         //logger.debug("value cloned: "+ clonedField.getValue());
413
saveField (clonedField, parentAclID, null);
414
415         return clonedField;
416
417     }
418
419
420     /**
421      * Builds the field structure for the specified page
422      *
423      * @param jData JahiaData
424      *
425      * @return a JahiaFieldSet object
426      */

427     public JahiaFieldSet buildFieldStructureForPage (JahiaData jData,
428                                                      EntryLoadRequest loadVersion)
429             throws JahiaException {
430         /*JahiaField theField = null;
431         Integer fieldID;
432
433         JahiaACLManagerService.getInstance().preloadFieldACLsByPage(jData.params ().getPage ().getID ());
434         ContentField.preloadActiveOrStagedFieldsByPageID (jData.params ().getPage ().getID ());
435
436         // loads all fields of the page
437         Vector fieldIDs = getNonContainerFieldIDsInPage (jData.params ().getPage ().getID ());*/

438         // composes the JahiaFieldSet
439
JahiaFieldSet theSet = new JahiaFieldSet (jData);
440 /*
441         for (int i = 0; i < fieldIDs.size (); i++) {
442             fieldID = (Integer) fieldIDs.elementAt (i);
443             // if we load active version, we cache it
444             if (loadVersion.isCurrent ()) {
445                 /*
446                  * ContentField are already preloaded now
447                  *
448                 // is the 1st field already loaded in cache? if no we load ALL the fields
449                 // from the page... (not a perfect way to check if we need to!)
450                 if ((i == 0) && (cacheFields.get (getCacheFieldActiveEntryKey(fieldID.intValue())) == null)) {
451                     // we should replace the load all field infos call with a
452                     // preload page fields for the content field.
453
454                     Vector allFields = fieldsDB.db_load_all_fields_info_from_page (
455                             jData.params ().getPage ().getID (), loadVersion);
456                     for (int j = 0; j < allFields.size (); j++) {
457                         theField = (JahiaField) allFields.get (j);
458                         loadField (theField,LoadFlags.ALL,jData.params(),loadVersion);
459                     }
460                 }*/

461 /*
462                 // Check the case of no active field.
463                 //theField = (JahiaField) cacheFields.get (getCacheFieldActiveEntryKey(fieldID.intValue()));
464
465                 if (theField == null) {
466                     // 04.09.2002 NK
467                     // staging & cache issue
468                     // Because of staging and activation, it is possible that
469                     // some validated fields are removed from cache
470                     // that is why we try to reload the active field from db.
471                     try {
472                         theField = loadField (fieldID.intValue (), jData.params ());
473                     } catch (JahiaException je) {
474                         // in case of no active field at all
475                     }
476                 }
477             } else {
478                 // staged fields are loaded from db
479                 theField = loadField (fieldID.intValue (), jData.params ());
480             }
481             if (theField != null) {
482                 theSet.addField (theField);
483             }
484         }
485 */

486         return theSet;
487     } // buildFieldStructureForPage
488

489
490     /**
491      * Gets all field list IDs in a page (from page ID)
492      *
493      * @param pageID the page ID
494      *
495      * @return A Vector of Integer corresponding to the field IDs.
496      */

497     public Vector JavaDoc getNonContainerFieldIDsInPage (int pageID)
498             throws JahiaException {
499         return f_utils.dbGetNonContainerFieldIDsInPage (pageID);
500     } // getFieldListIDsInPage
501

502     /**
503      * Gets all field IDs in a page in a specified workflow state
504      *
505      * @param pageID the page ID.
506      * @param loadVersion the workflow state field to load.
507      *
508      * @return A Vector of Integer corresponding to the field IDs.
509      */

510     public Vector JavaDoc getNonContainerFieldIDsInPageByWorkflowState (int pageID,
511                                                                 EntryLoadRequest loadVersion)
512             throws JahiaException {
513         return f_utils.dbGetNonContainerFieldIDsInPageByWorkflowState (pageID, loadVersion);
514     }
515
516     /**
517      * Retrieves all the ContentFieldEntryStates for the fields on a page that
518      * are *NOT* contained in a container (ie directly attached to the page).
519      *
520      * @param pageID the identifier of the page for which to retrieve the
521      * field entry states
522      *
523      * @return a SortedSet of ContentFieldEntryState objects that contain the
524      * cumulation of all the field's entrystates.
525      *
526      * @throws JahiaException thrown if there was a problem retrieving field
527      * data from the database.
528      */

529     public SortedSet JavaDoc getNonContainerFieldEntryStateInPage (int pageID)
530             throws JahiaException {
531         SortedSet JavaDoc entryStates = new TreeSet JavaDoc ();
532         Vector JavaDoc fieldIDs = getNonContainerFieldIDsInPage (pageID);
533         Enumeration JavaDoc fieldIDEnum = fieldIDs.elements ();
534         while (fieldIDEnum.hasMoreElements ()) {
535             Integer JavaDoc curFieldID = (Integer JavaDoc) fieldIDEnum.nextElement ();
536             ContentField curField = ContentField.getField (curFieldID.intValue ());
537             entryStates.addAll (curField.getEntryStates ());
538         }
539         return entryStates;
540     }
541
542     /**
543      * Given a page ID, get all the IDs of the page links contained in
544      * the page, whether of type DIRECT, INTERNAL or URL
545      *
546      * @param pageID the page ID
547      *
548      * @return a Vector of Field list IDs
549      */

550     public Vector JavaDoc getPagefieldIDsInPage (int pageID)
551             throws JahiaException {
552         return f_utils.db_get_pagefield_ids_in_page (pageID);
553     } // getPagefieldIDsInPage
554

555
556     /**
557      * Gets a field ID from its name and page id
558      *
559      * @param fieldName the field name
560      * @param pageID the page ID
561      *
562      * @return a field id
563      */

564     public int getFieldID (String JavaDoc fieldName, int pageID)
565             throws JahiaException {
566         return f_utils.db_get_field_id (fieldName, pageID);
567     } // getFieldListIDsInPage
568

569
570     /**
571      * Get all the fields ID for a gived site (for the search engine)
572      *
573      * @param siteID the site id
574      *
575      * @return a Vector of field ids
576      */

577     public Vector JavaDoc getAllFieldIDs (int siteID)
578             throws JahiaException {
579
580         return f_utils.db_get_all_fields_id (siteID);
581
582     }
583
584
585     /**
586      * Get all the fields ID (for the search engine)
587      *
588      * @return a Vector of field ids
589      */

590     public Vector JavaDoc getAllFieldIDs ()
591             throws JahiaException {
592         return f_utils.db_get_all_fields_id ();
593     } // getAllFieldIDs
594

595
596     /**
597      * gets all the field definition ids
598      * to be changed, using a fielddefinition cache instead and changing the def registry.
599      *
600      * @return a Vector of field definition ids
601      */

602     public Vector JavaDoc getAllFieldDefinitionIDs ()
603             throws JahiaException {
604         return f_utils.db_get_all_field_definition_ids ();
605     } // getAllFieldDefinitionIDs
606

607
608
609     /**
610      * loads a field from the database, no other info than what's in the database
611      * NO RIGHTS CHECKS! use another loadField method (with jParams) for that.
612      *
613      * @param fieldID the field ID
614      * @return a JahiaField object
615      * @see org.jahia.data.fields.JahiaField
616      *
617      */

618
619     /*
620  private JahiaField loadFieldInfo( int fieldID )
621  throws JahiaException
622  {
623      return loadFieldInfo (fieldID, EntryLoadRequest.CURRENT);
624  }
625
626  private JahiaField loadFieldInfo( int fieldID, EntryLoadRequest loadVersion )
627  throws JahiaException
628  {
629      // if we don't load current version, we load it from database
630      if (!loadVersion.isCurrent())
631      {
632          return fieldsDB.db_load_field( fieldID, loadVersion );
633      } else
634      // else we load it from cache
635      {
636          JahiaField theField = (JahiaField) cacheFields.getValue (new Integer(fieldID));
637          // not already in cache -> we must load it
638          if (theField == null)
639          {
640              theField = fieldsDB.db_load_field( fieldID, loadVersion );
641              if (theField != null) {
642                  // we only cache it if it's the active version
643                  if (loadVersion.isCurrent())
644                      cacheFields.setValue ( new Integer(fieldID), theField);
645              } else {
646                  throw new JahiaException ("Error loading field data",
647                                            "Error loading field with ID " +
648                                            Integer.toString(fieldID),
649                                            JahiaException.DATABASE_ERROR,
650                                            JahiaException.ERROR_SEVERITY);
651              }
652          }
653          return (JahiaField)theField.clone();
654      }
655
656  } // loadField
657  */

658
659
660     /**
661      * loads a field from the database, according to the loadflags
662      * NO RIGHTS CHECKS! use another loadField method (with jParams) for that.
663      *
664      * @param fieldID the field ID
665      * @param loadFlag the load flags
666      *
667      * @return a JahiaField object
668      *
669      * @see org.jahia.data.fields.JahiaField
670      * @see org.jahia.data.fields.LoadFlags
671      */

672     public JahiaField loadField (int fieldID, int loadFlag)
673             throws JahiaException {
674         return loadField (fieldID, loadFlag, null);
675     } // end loadField
676

677
678     /**
679      * loads a field from the database, with all values
680      *
681      * @param fieldID the field ID
682      * @param jParams the ParamBean object with request and response
683      *
684      * @return a JahiaField object
685      *
686      * @see org.jahia.data.fields.JahiaField
687      * @see org.jahia.data.fields.LoadFlags
688      */

689     public JahiaField loadField (int fieldID, ParamBean jParams)
690             throws JahiaException {
691         return loadField (fieldID, LoadFlags.ALL, jParams);
692     } // loadField
693

694
695     /**
696      * loads a field, and accept loadFlag and ParamBean <br/>
697      * uses loadField ( int fieldID ) method to access cache/database
698      *
699      * @param fieldID the field ID
700      * @param loadFlag the load flags
701      * @param jParams ParamBean
702      *
703      * @return a JahiaField object
704      * DJ 28.01.2001 added ACL support
705      * DJ 28.01.2001 added ACL support
706      * DJ 28.01.2001 added ACL support
707      */

708     // DJ 28.01.2001 added ACL support
709

710     public JahiaField loadField (int fieldID, int loadFlag, ParamBean jParams)
711             throws JahiaException {
712         if (jParams != null) {
713             return loadField (fieldID, loadFlag, jParams, jParams.getEntryLoadRequest ());
714         } else {
715             logger.debug (
716                     "LEGACY : Loading current version by default ! Try to use the newer APIs to avoid this message! ");
717             return loadField (fieldID, loadFlag, jParams, EntryLoadRequest.CURRENT);
718
719         }
720     }
721
722     public JahiaField loadField (int fieldID, int loadFlag, ParamBean jParams,
723                                  EntryLoadRequest loadVersion)
724             throws JahiaException {
725         JahiaField theField = null;
726 // synchronized(this) {
727
if (logger.isDebugEnabled()) {
728                 String JavaDoc msg = "loading field: id=" + fieldID ;
729                 if ( loadVersion != null ){
730                     msg += " loadVersion=[" + loadVersion.toString() + "]";
731                 }
732                 logger.debug(msg);
733             }
734
735             ContentField contentField = null;
736             if (theField == null) {
737                 // field was not found in cache or is not available in active mode.
738
contentField = ContentField.getField(fieldID);
739                 if (contentField == null) {
740                     return null;
741                 }
742                 theField = contentFieldToJahiaField(contentField, loadVersion);
743             }
744
745             if (theField == null) {
746                 return null;
747             }
748
749             if ( loadVersion.isCurrent()
750                     && theField.getWorkflowState() != EntryLoadRequest.ACTIVE_WORKFLOW_STATE ){
751                 // we only allow live data
752
return null;
753             } else if ( loadVersion.isStaging() ){
754                 if (!loadVersion.isWithMarkedForDeletion()
755                         && contentField.isMarkedForDelete(theField.getLanguageCode())) {
756                     // we don't want marked for delete data
757
return null;
758                 }
759             }
760
761             /* Doesn't work with engine like "searchengine"
762             if ( theField != null
763             && !"core".equalsIgnoreCase(jParams.getEngine()) ){
764             // we found an active but we need to check that it is not marked for delete
765             if (contentField == null) {
766             contentField = ContentField.getField(fieldID);
767             }
768             if ( contentField.isMarkedForDelete(theField.getLanguageCode()) ){
769             return null;
770             }
771             }*/

772
773             // check fields ACL
774
if (jParams == null) {
775                 // logger.debug ("loadField(" + theField.getDefinition().getName() + "): can't check ACL, method called without ParamBean");
776
} else {
777                 JahiaUser currentUser = jParams.getUser ();
778                 if (currentUser != null) {
779                     // logger.debug("loadField(" + theField.getDefinition().getName() + "): checking rights...");
780
// If containerId is greater than zero then the fieldRights are defined in the container list properties
781
// so we must get the container list and check
782
if (theField.getctnid() > 0) {
783                         JahiaContainersService jahiaContainersService = ServicesRegistry.getInstance().getJahiaContainersService();
784                         JahiaData jData = (JahiaData) jParams.getRequest().getAttribute( "org.jahia.data.JahiaData" );
785                         
786                         JahiaContainer container = jData != null && jData.containers() != null && loadVersion.equals(jParams.getEntryLoadRequest()) ? jData.containers().getContainer(theField.getctnid()) :
787                              jahiaContainersService.loadContainer(theField.getctnid(), loadFlag, jParams, loadVersion);
788                         if (container != null) {
789                             JahiaContainerList containerList = jData != null && jData.containers() != null && loadVersion.equals(jParams.getEntryLoadRequest()) ? jData.containers().getContainerList(container.getListID()) :
790                                 jahiaContainersService.loadContainerList(container.getListID(), loadFlag, jParams);
791                             if (containerList!=null && !containerList.isFieldReadable(theField.getDefinition().getName(), currentUser)) {
792                                 if (theField.getValue().toUpperCase().indexOf("JAHIA_LINKONLY") == -1) {
793                                     theField.setValue(""); // return an empty field
794
}
795                                 return theField;
796                             }
797                         }
798                     }
799                     // if the user has no read rights, return the field with an empty value.
800
else if (!theField.checkReadAccess (currentUser)) {
801                         //logger.debug ("loadField(" + theField.getDefinition().getName() + "): NO read rights! -> return an empty field");
802
if (theField.getValue ().toUpperCase ().indexOf ("JAHIA_LINKONLY") == -1) {
803                             theField.setValue (""); // return an empty field
804
}
805                         return theField;
806                     }
807                     // logger.debug ("loadField(" + theField.getDefinition().getName() + "): read rights OK");
808
} else {
809                     throw new JahiaException ("No user present !",
810                             "No current user defined in the params in loadField() method.",
811                             JahiaException.USER_ERROR, JahiaException.ERROR_SEVERITY);
812                 }
813             }
814 // }
815

816         // We can use the Field Cache only to store instance of JahiaField
817
// but each time we get it from this cache, we need to call it's load()
818
// method to ensure dynamically Expression evaluation and Contextual
819
// ( multilanguage ) processing of field value.
820
loadField(theField,loadFlag,jParams,loadVersion);
821
822         return theField;
823
824     } // loadField
825

826     /**
827      * Performing the complete load on an existing JahiaField instance
828      *
829      * @param theField
830      * @param loadFlag
831      * @param jParams
832      * @param loadVersion
833      * @return
834      * @throws JahiaException
835      */

836     private JahiaField loadField (JahiaField theField, int loadFlag, ParamBean jParams,
837                                  EntryLoadRequest loadVersion)
838             throws JahiaException {
839
840         if ( theField == null ){
841             return null;
842         }
843
844         if (logger.isDebugEnabled()) {
845             logger.debug(
846                 "loading field: id=" + theField.getID() + " loadVersion=[" +
847                 loadVersion.toString());
848         }
849
850         // now we compose the content of fieldValue, depending of the field type and the loadFlag
851

852         boolean fieldLoadedSuccessfully = false;
853         // @todo : find a better way
854
try {
855             jParams.setSubstituteEntryLoadRequest (loadVersion);
856             logger.debug ("Calling field specific load");
857             theField.load (loadFlag, jParams);
858             fieldLoadedSuccessfully = true;
859         } catch (Throwable JavaDoc t) {
860             logger.debug ("Error calling field load method fid[" + theField.getID () + "]", t);
861             // Return the field anyway
862
/*
863             throw new JahiaException ("Error calling field specific load method !",
864                     "Error calling field specific load method !",
865                     JahiaException.DATA_ERROR, JahiaException.ERROR_SEVERITY);
866             */

867         } finally {
868             jParams.resetSubstituteEntryLoadRequest ();
869         }
870
871         if (theField.getValue () != null && theField.getValue ().equals ("<empty>")) {
872             theField.setValue ("");
873         }
874
875         if ((theField != null) && (fieldLoadedSuccessfully)) {
876             if ( !(loadVersion.isVersioned()) ) {
877                 // FIXME it is a quick short way to deactivate cache of JahiaField by never cache them.
878
// We should condidere caching ContentField object only,
879
// not JahiaField.
880
// cacheFields.put(getCacheFieldEntryKey(theField.getID(), theField.getWorkflowState()),
881
// theField);
882
}
883         }
884
885         return theField;
886     } // loadField
887

888     /**
889      * saves a field if the user has the correct rights.
890      * Check user's rights
891      *
892      * @param theField the JahiaField to save
893      * @param parentAclID the Acl parent ID (or 0 to keep existing parent ACL ID)
894      * @param jParams ParamBean
895      */

896     public void saveField (JahiaField theField, int parentAclID, ParamBean jParams)
897             throws JahiaException {
898         logger.debug ("saving field #" + theField.getID ());
899         //(new Throwable()).printStackTrace();
900
String JavaDoc createField = "";
901         if (theField.getObject () instanceof String JavaDoc) {
902             createField = (String JavaDoc) theField.getObject ();
903         }
904
905         // Check the ACL.
906
if (jParams != null) {
907             JahiaUser currentUser = jParams.getUser ();
908             if (currentUser != null) {
909                 logger.debug ("checking rights...");
910                 // if the user has no write rights, exit.
911
// if fieldID = 0 then let's say the user can write (add)
912
if ((!theField.checkWriteAccess (currentUser)) && (theField.getID () != 0)) {
913                     if (createField.equals ("createFieldWithCurrentID")) {
914                         logger.debug ("write rights OK");
915                     } else {
916                         logger.debug ("NO write right");
917                         return;
918                     }
919                 }
920                 //logger.debug ("saveField(): write rights OK");
921
} else {
922                 throw new JahiaException ("No user present !",
923                         "No current user defined in the params in saveField() method.",
924                         JahiaException.USER_ERROR, JahiaException.ERROR_SEVERITY);
925             }
926         }
927
928         int savemode = 1; // 0 = create, 1 = update
929

930
931         if (createField.equals ("createFieldWithCurrentID")) {
932             //logger.debug("########### createFieldWithcurrentID- set savemode");
933
theField.setObject (null);
934             // the fielID is given in theField, because we want to re-create the field
935
savemode = 0;
936         }
937
938         if (theField.getID () == 0) {
939             // gets the field id
940
int theFieldID = ServicesRegistry.getInstance ().getJahiaIncrementorsDBService ()
941                     .autoIncrement ("jahia_fields_data");
942             theField.setID (theFieldID);
943             logger.debug("New field ID attributed="+ theFieldID);
944             savemode = 0;
945         }
946
947         int pageDefID = 0;
948
949         if ( theField.getDefinition().getJahiaID() != 0 ){
950             ContentPage jahiaPage = ContentPage.getPage(theField.getPageID());
951             pageDefID = jahiaPage.getPageTemplateID(jParams);
952         }
953         
954         String JavaDoc errorMsg = "";
955         if (theField.getDefinition ().getName ().equals ("")) {
956             errorMsg = "Error in FieldBaseService : field name value is an empty string";
957         }
958         if (theField.getDefinition ().getTitle (pageDefID).equals ("")) {
959             errorMsg = "Error in FieldBaseService : field title value is an empty string";
960         }
961         if ((theField.getValue () != null) && theField.getValue ().equals ("")) {
962             theField.setValue ("<empty>");
963         }
964
965         if (errorMsg != "") {
966             //logger.debug( errorMsg );
967
throw new JahiaException ("Cannot update fields in the database",
968                     errorMsg, JahiaException.DATABASE_ERROR, JahiaException.CRITICAL_SEVERITY);
969         }
970
971         // determines field type
972
int fieldType = theField.getDefinition ().getType (pageDefID);
973         if (fieldType == FieldTypes.UNDEFINED) {
974             fieldType = theField.getType ();
975         }
976
977         // sets field value in tmpVal
978
String JavaDoc tmpVal = "";
979         if (fieldType == FieldTypes.BIGTEXT) {
980             tmpVal = "<text>";
981         }
982         if (theField.getValue () != null) {
983             tmpVal = theField.getValue ();
984         }
985
986         // creates ACL, if needed
987
if (theField.getAclID () == 0) {
988             if ( theField.getctnid() == 0){
989                 JahiaBaseACL acl = new JahiaBaseACL ();
990                 if (acl != null) {
991                     // create a new object by specifying the parent ACL ID (a container)
992
if (!acl.create (parentAclID)) {
993                         String JavaDoc message = "Could not create an ACL object for a new field in container.";
994                         logger.debug (message + " -> Stop container creation!");
995                         throw new JahiaException ("AddContainer_Engine", message,
996                                 JahiaException.ACL_ERROR, JahiaException.CRITICAL_SEVERITY);
997                     } else {
998                         logger.debug ("ACL [" + acl.getID () + "] has just been created!");
999                     }
1000                } else {
1001                    throw new JahiaException ("JahiaFieldBaseService.saveField", "Could not instanciate the JahiaBaseACL class",
1002                            JahiaException.ACL_ERROR, JahiaException.CRITICAL_SEVERITY);
1003                }
1004                // End Create ACL
1005
theField.setAclID (acl.getID ());
1006            } else {
1007                theField.setAclID (parentAclID);
1008            }
1009        }
1010
1011
1012        //--------- start add to search engine + fire event --------------
1013
if (savemode == 0)
1014        // CREATE
1015
{
1016            logger.debug ("CREATE - savemode: " + savemode);
1017            //JahiaField theTempField = (JahiaField)theField.clone();
1018
//theTempField.setValue (tmpVal);
1019
theField.setValue (tmpVal);
1020
1021            fieldsDB.db_create_field (theField,
1022                    ServicesRegistry.getInstance ().getJahiaVersionService ()
1023                    .getSiteSaveVersion (theField.getJahiaID ()));
1024
1025            // Invalidate FieldIDs by container cache
1026
if ( theField != null ){
1027                FieldsChangeEventListener listener = new FieldsChangeEventListener();
1028                listener.notifyChange(theField.getID());
1029            }
1030
1031            // if not in staging, we set the value
1032

1033            /*
1034            if (!ServicesRegistry.getInstance ().getJahiaVersionService ().getSiteSaveVersion (
1035                    theField.getJahiaID ())
1036                    .isStaging ())
1037                cacheFields.put (getCacheFieldEntryKey(theField.getID (), theField.getWorkflowState()), theField);
1038             */

1039
1040            // Search Engine
1041
/*
1042            if ( (theField.getConnectType() == ConnectionTypes.LOCAL) ||
1043                 (theField.getConnectType() == ConnectionTypes.HTMLEDITOR) ||
1044                 (theField.getConnectType() == ConnectionTypes.HTMLEDITORAX) )
1045            {
1046                int workflowState = theField.getWorkflowState();
1047                if ( workflowState == EntryLoadRequest.ACTIVE_WORKFLOW_STATE ){
1048                    workflowState = EntryLoadRequest.STAGING_WORKFLOW_STATE;
1049                }
1050                ServicesRegistry.getInstance().getJahiaSearchService().addFieldToSearchEngine( theField , workflowState);
1051            }*/

1052
1053        } else
1054        // UPDATE
1055
{
1056            logger.debug ("UPDATE - savemode: " + savemode);
1057            //boolean isStagingEnabled = ServicesRegistry.getInstance ().getJahiaVersionService ().isStagingEnabled (theField.getJahiaID ());
1058

1059            // never used ??
1060
//JahiaField oldField = this.loadField( theField.getID(), LoadFlags.TEXTS, jParams );
1061

1062            logger.debug ("UPDATE - step1 ");
1063
1064            /*
1065            JahiaField theTempField = (JahiaField)theField.clone();
1066            theTempField.setValue (tmpVal);
1067            */

1068            theField.setValue (tmpVal);
1069
1070            logger.debug ("UPDATE - step2 ");
1071
1072            fieldsDB.db_update_field (theField,
1073                    ServicesRegistry.getInstance ().getJahiaVersionService ()
1074                    .getSiteSaveVersion (theField.getJahiaID ()));
1075
1076            logger.debug ("UPDATE - step3 ");
1077
1078            // if it is current version, we set the value
1079

1080            /*
1081            if (!ServicesRegistry.getInstance ().getJahiaVersionService ().getSiteSaveVersion (
1082                    theField.getJahiaID ())
1083                    .isStaging ())
1084                cacheFields.put (getCacheFieldEntryKey(theField.getID (), theField.getWorkflowState()), theField);
1085             */

1086
1087            invalidateCacheField(theField.getID());
1088
1089            /*
1090            int workflowState = theField.getWorkflowState();
1091            if ( workflowState == EntryLoadRequest.ACTIVE_WORKFLOW_STATE ){
1092                workflowState = EntryLoadRequest.STAGING_WORKFLOW_STATE;
1093            }
1094            if (theField.getConnectType() == ConnectionTypes.LOCAL) {
1095                ServicesRegistry.getInstance().getJahiaSearchService().addFieldToSearchEngine( theField, workflowState );
1096            }
1097            // JB 02.08.2001 - Add HTMLEditor Types
1098            if (theField.getConnectType() == ConnectionTypes.HTMLEDITOR) {
1099                ServicesRegistry.getInstance().getJahiaSearchService().addFieldToSearchEngine( theField, workflowState);
1100            }
1101            if (theField.getConnectType() == ConnectionTypes.HTMLEDITORAX) {
1102                ServicesRegistry.getInstance().getJahiaSearchService().addFieldToSearchEngine( theField, workflowState );
1103            }*/

1104
1105            logger.debug ("UPDATE - step4 ");
1106
1107            // fire event if we're not in a PortletList container
1108
if (logMe (theField)) {
1109                JahiaEvent theEvent = new JahiaEvent (this, jParams, theField);
1110                ServicesRegistry.getInstance ().getJahiaEventService ().
1111                        fireUpdateField (theEvent);
1112            }
1113        }
1114        //--------- end add to search engine + fire event --------------
1115

1116        //JahiaSaveVersion saveVersion = ServicesRegistry.getInstance ().getJahiaVersionService ().getSiteSaveVersion (theField.getJahiaID ());
1117
// saves field additionnal info, if needed
1118
theField.save (jParams);
1119
1120        // fire event if we're not in a PortletList container
1121
if (jParams != null) {
1122            // fire event if we're not in a PortletList container
1123
if (logMe (theField)) {
1124                JahiaEvent theEvent = new JahiaEvent (this, jParams, theField);
1125                if (savemode == 0) {
1126                    ServicesRegistry.getInstance ().getJahiaEventService ().
1127                            fireAddField (theEvent);
1128                } else {
1129                    ServicesRegistry.getInstance ().getJahiaEventService ().
1130                            fireUpdateField (theEvent);
1131                }
1132            }
1133        }
1134
1135    } // saveField
1136

1137
1138    /**
1139     * deletes a field
1140     *
1141     * @param fieldID the field id to delete
1142     */

1143
1144    public void deleteField (int fieldID, ParamBean jParams)
1145            throws JahiaException {
1146        ContentField contentField = ContentField.getField (fieldID);
1147        jParams.setSubstituteEntryLoadRequest (EntryLoadRequest.STAGED);
1148        JahiaField theField = contentFieldToJahiaField (contentField,
1149                jParams.getEntryLoadRequest ());
1150        jParams.resetSubstituteEntryLoadRequest ();
1151        // JahiaField theField = loadFieldInfo( fieldID, EntryLoadRequest.STAGED );
1152

1153        boolean doIndexField = !ServicesRegistry.getInstance ().getJahiaSitesService ()
1154                .isSiteToBeDeleted (theField.getJahiaID ());
1155
1156        if (theField.getConnectType () == ConnectionTypes.LOCAL) {
1157            if (doIndexField) {
1158                ServicesRegistry.getInstance ().getJahiaSearchService ()
1159                        .removeFieldFromSearchEngine (theField);
1160            }
1161        }
1162
1163        // JB 02.08.2001 - Add HTMLEditor Types
1164
if (theField.getConnectType () == ConnectionTypes.HTMLEDITOR) {
1165            if (doIndexField) {
1166                ServicesRegistry.getInstance ().getJahiaSearchService ()
1167                        .removeFieldFromSearchEngine (theField);
1168            }
1169        }
1170        if (theField.getConnectType () == ConnectionTypes.HTMLEDITORAX) {
1171            if (doIndexField) {
1172                ServicesRegistry.getInstance ().getJahiaSearchService ()
1173                        .removeFieldFromSearchEngine (theField);
1174            }
1175        }
1176
1177        int pageDefID = ServicesRegistry.getInstance ().getJahiaPageService ().
1178                lookupPage (theField.getPageID (), jParams).getPageTemplateID ();
1179
1180        int fieldType = theField.getDefinition ().getType (pageDefID);
1181        if (fieldType == FieldTypes.UNDEFINED) {
1182            fieldType = theField.getType ();
1183        }
1184
1185        // remember the save version
1186
JahiaSaveVersion saveVersion = ServicesRegistry.getInstance ().getJahiaVersionService ()
1187                .getSiteSaveVersion (theField.getJahiaID ());
1188        // delete info specific to field type
1189
theField.delete (jParams);
1190
1191/* try {
1192        // do not delete the ACL anymore (temporary) because of staging & versioning
1193        // JahiaBaseACL theACL = new JahiaBaseACL (theField.getAclID());
1194        // theACL.delete ();
1195    }
1196    catch (ACLNotFoundException ex) {
1197        JahiaException je = new JahiaException ("", "Could not find the ACL ["+Integer.toString (theField.getAclID())+
1198                            "] while removing field ["+Integer.toString(fieldID)+"]",
1199                            JahiaException.ACL_ERROR, JahiaException.WARNING);
1200    }*/

1201        if (logMe (theField)) {
1202            JahiaEvent theEvent = new JahiaEvent (this, jParams, theField);
1203            ServicesRegistry.getInstance ().getJahiaEventService ().
1204                    fireDeleteField (theEvent);
1205        }
1206
1207        fieldsDB.db_delete_field (theField.getID (), saveVersion);
1208        // if it's not in staging version we remove it from cache
1209
if (!saveVersion.isStaging ()) {
1210            invalidateCacheField(theField.getID());
1211        }
1212    } // deleteField
1213

1214    public void markPageFieldsLanguageForDeletion (int pageID,
1215                                                   JahiaUser user,
1216                                                   String JavaDoc languageCode,
1217                                                   StateModificationContext
1218            stateModifContext)
1219            throws JahiaException {
1220        Vector JavaDoc fieldIDs = f_utils.getActiveOrStagedFieldIDsInPage (pageID);
1221        for (int i = 0; i < fieldIDs.size (); i++) {
1222            int id = ((Integer JavaDoc) fieldIDs.elementAt (i)).intValue ();
1223
1224            ContentField theField = ContentField.getField (id);
1225            // We have to delete direct page field only ( fields that aren't in a container ! )
1226
// fields that are inside a container should not be deleted here,
1227
// but when deleting these containers.
1228
if (theField != null && (theField.getContainerID () == 0)) {
1229                theField.markLanguageForDeletion (user, languageCode, stateModifContext);
1230            }
1231        }
1232    }
1233
1234    public void purgePageFields (int pageID)
1235            throws JahiaException {
1236        Vector JavaDoc fieldIDs = f_utils.dbGetNonContainerFieldIDsInPage (pageID);
1237        for (int i = 0; i < fieldIDs.size (); i++) {
1238            int id = ((Integer JavaDoc) fieldIDs.elementAt (i)).intValue ();
1239            ContentField theField = ContentField.getField (id);
1240            theField.purge ();
1241        }
1242    }
1243
1244    public ActivationTestResults areFieldsValidForActivation (
1245            Set JavaDoc languageCodes,
1246            int pageID,
1247            JahiaUser user,
1248            JahiaSaveVersion saveVersion,
1249            ParamBean jParams,
1250            StateModificationContext stateModifContext)
1251            throws JahiaException {
1252
1253        Vector JavaDoc fieldIDs = f_utils.db_get_only_staged_field_ids_in_page (pageID);
1254
1255        ActivationTestResults activationResults = new ActivationTestResults ();
1256        // for each field, we check if the user has write+admin access to it,
1257
// if so we can validate it
1258
for (int i = 0; i < fieldIDs.size (); i++) {
1259            int id = ((Integer JavaDoc) fieldIDs.elementAt (i)).intValue ();
1260
1261            ContentField theField = ContentField.getField (id);
1262            ActivationTestResults fieldResult = theField.isValidForActivation (languageCodes,
1263                    jParams, stateModifContext);
1264
1265            if (fieldResult.getStatus () == ActivationTestResults.FAILED_OPERATION_STATUS) {
1266                fieldResult.setStatus (ActivationTestResults.PARTIAL_OPERATION_STATUS);
1267                fieldResult.moveErrorsToWarnings ();
1268            }
1269            activationResults.merge (fieldResult);
1270
1271        }
1272        return activationResults;
1273
1274    }
1275
1276    public ActivationTestResults areNonContainerFieldsValidForActivation (
1277            Set JavaDoc languageCodes,
1278            int pageID,
1279            JahiaUser user,
1280            JahiaSaveVersion saveVersion,
1281            ParamBean jParams,
1282            StateModificationContext stateModifContext)
1283            throws JahiaException {
1284
1285        Vector JavaDoc fieldIDs = f_utils.db_get_only_staged_non_container_field_ids_in_page (pageID);
1286
1287        ActivationTestResults activationResults = new ActivationTestResults ();
1288        // for each field, we check if the user has write+admin access to it,
1289
// if so we can validate it
1290
for (int i = 0; i < fieldIDs.size (); i++) {
1291            int id = ((Integer JavaDoc) fieldIDs.elementAt (i)).intValue ();
1292
1293            ContentField theField = ContentField.getField (id);
1294            ActivationTestResults fieldResult = theField.isValidForActivation (languageCodes,
1295                    jParams, stateModifContext);
1296            activationResults.merge (fieldResult);
1297
1298        }
1299        return activationResults;
1300
1301    }
1302
1303
1304    /**
1305     * Validate the fields of the page to which the user has admin AND write access
1306     * i.e. now Staged fields are Active.
1307     * No rights checks are done here.
1308     *
1309     * @param saveVersion it must contain the right versionID and staging/versioning
1310     * info of the current site
1311     */

1312    public ActivationTestResults activateStagedFields (
1313            Set JavaDoc languageCodes,
1314            int pageID,
1315            JahiaUser user,
1316            JahiaSaveVersion saveVersion,
1317            ParamBean jParams,
1318            StateModificationContext stateModifContext) throws JahiaException {
1319
1320        ActivationTestResults activationResults = new ActivationTestResults ();
1321
1322        /** FIXME : this test has no meaning, because, areFieldsValidForActivation(...)
1323         * always move Error status to Warning status !!!!! */

1324        activationResults.merge (
1325                areFieldsValidForActivation (languageCodes, pageID, user, saveVersion, jParams,
1326                        stateModifContext));
1327        if (activationResults.getStatus () == ActivationTestResults.FAILED_OPERATION_STATUS) {
1328            return activationResults;
1329        }
1330
1331        Vector JavaDoc fieldIDs = f_utils.db_get_only_staged_field_ids_in_page (pageID);
1332        // for each field, we check if the user has write+admin access to it,
1333
// if so we can validate it
1334
for (int i = 0; i < fieldIDs.size (); i++) {
1335            int id = ((Integer JavaDoc) fieldIDs.elementAt (i)).intValue ();
1336            logger.debug ("Attempting to validate field : " + id);
1337
1338            // should we add right checks here as they were previously ?
1339

1340            ContentField contentField = ContentField.getField (id);
1341            if ( contentField instanceof ContentPageField ){
1342                // NK
1343
// There are some issues with Page Move and Activation
1344
// Suppose this page field is marked for delete because its page
1345
// is moved to another location.
1346
// If we activate this field without acitvating
1347
// the moved page, we create an inconsistant state that can
1348
// make the moved page a Phantom page ( not referred by any page field),
1349
// it is the case if we fail activate the moved page accordingly with this page field.
1350
// We can either skip activate this field ( it would be activate only when
1351
// directly applying activation on the moved page, which internally handle correctly
1352
// page move ).
1353
//..handled in contentField is content valid for activation check
1354
ActivationTestResults fieldResult =
1355                    contentField.isValidForActivation (languageCodes, jParams, stateModifContext);
1356                if ( fieldResult.getStatus () ==
1357                     ActivationTestResults.FAILED_OPERATION_STATUS ){
1358                    continue;
1359                }
1360            }
1361
1362             // fire event
1363
JahiaEvent theEvent = new JahiaEvent( saveVersion, jParams, contentField );
1364             ServicesRegistry.getInstance().getJahiaEventService()
1365                     .fireBeforeFieldActivation(theEvent);
1366
1367            ActivationTestResults contentResult = contentField.activate (languageCodes,
1368                    saveVersion.getVersionID (), jParams, stateModifContext);
1369
1370            activationResults.merge (contentResult);
1371            if (contentResult.getStatus () == ActivationTestResults.COMPLETED_OPERATION_STATUS) {
1372                // invalidate corresponding cache entries
1373
invalidateCacheField(id);
1374            } else {
1375                logger.debug (
1376                        "Field " + id + " activation not completely performed. testResult=" + contentResult);
1377            }
1378        }
1379
1380
1381        return activationResults;
1382    }
1383
1384    /**
1385     * Sets the workflow state for all the field in a page for a given set
1386     * of languages.
1387     *
1388     * @param languageCodes the set of language for which to change the state
1389     * in the fields
1390     * @param newWorkflowState the new workflow state for the fields
1391     * @param pageID the page on which
1392     * @param jParams a ParamBean used by the individual fields to change their
1393     * state
1394     *
1395     * @throws JahiaException in the case there were problems communicating
1396     * with the persistant storage system
1397     */

1398    public void setFieldsLanguageStates (
1399            Set JavaDoc languageCodes,
1400            int newWorkflowState,
1401            int pageID,
1402            ParamBean jParams,
1403            StateModificationContext stateModifContext) throws JahiaException {
1404        Vector JavaDoc fieldIDs = f_utils.db_get_only_staged_field_ids_in_page (pageID);
1405        // for each field, we check if the user has write+admin access to it,
1406
// if so we can validate it
1407
for (int i = 0; i < fieldIDs.size (); i++) {
1408            int id = ((Integer JavaDoc) fieldIDs.elementAt (i)).intValue ();
1409
1410            // should we add right checks here as they were previously ?
1411

1412            ContentField contentField = ContentField.getField (id, true);
1413            contentField.setWorkflowState (languageCodes, newWorkflowState, jParams,
1414                    stateModifContext);
1415        }
1416
1417    }
1418
1419
1420    /**
1421     * Returns the staging workflow state of the fields for all the languages
1422     * on the specified page.
1423     * Normally as currently we only do state changes on a page basis these
1424     * should all be equal. This does not retrieve the state of absolute fields.
1425     *
1426     * @param pageID the page id on which to retrieve the fields workflow state
1427     *
1428     * @return a Map that contains all the states of the languages for the
1429     * fields on the page (for the moment we assume all the objects are in the
1430     * same state)
1431     *
1432     * @throws JahiaException in the case we couldn't load a field.
1433     */

1434    public Map JavaDoc getFieldsLanguagesState (int pageID)
1435            throws JahiaException {
1436
1437        return f_utils.getFieldsLanguagesState(pageID);
1438    }
1439
1440    /**
1441     * Loads a Field Definition by its id
1442     *
1443     * @param defID the field definition id
1444     *
1445     * @return a JahiaFieldDefinition object
1446     *
1447     * @see org.jahia.data.fields.JahiaFieldDefinition
1448     */

1449    public JahiaFieldDefinition loadFieldDefinition (int defID)
1450            throws JahiaException {
1451        return f_defs.db_load_field_definition (defID);
1452    } // loadFieldDefinition
1453

1454    /**
1455     * Load a field definition by it's siteID and definition name
1456     *
1457     * @param siteID the identifier for the site for which to load the
1458     * definition
1459     * @param definitionName the unique identifier name for the definition on
1460     * the site
1461     *
1462     * @return a valid JahiaFieldDefinition object if found in the database.
1463     *
1464     * @throws JahiaException if there was a problem communicating with the
1465     * database.
1466     */

1467    public JahiaFieldDefinition loadFieldDefinition (int siteID,
1468                                                     String JavaDoc definitionName)
1469            throws JahiaException {
1470        return f_defs.db_load_field_definition (siteID, definitionName);
1471    } // loadFieldDefinition
1472

1473
1474    /**
1475     * Saves a Field Definition
1476     *
1477     * @param theDef the JahiaFieldDefinition object to save
1478     *
1479     * @see org.jahia.data.fields.JahiaFieldDefinition
1480     */

1481    public void saveFieldDefinition (JahiaFieldDefinition theDef)
1482            throws JahiaException {
1483        if (theDef.getID () == 0 || theDef.getID () == -1) {
1484            f_defs.db_create_field_definition (theDef);
1485        } else {
1486            f_defs.db_update_field_defprop (theDef);
1487        }
1488    } // saveFieldDefinition
1489

1490    /**
1491     * Delete a Field Definition and it's sub definition.
1492     *
1493     * @param fieldDefID the field def ID
1494     */

1495    public void deleteFieldDefinition (int fieldDefID)
1496            throws JahiaException {
1497
1498        logger.debug ("fieldDef=" + fieldDefID);
1499        //remove from registry
1500
JahiaFieldDefinitionsRegistry.getInstance ().removeFieldDefinition (fieldDefID);
1501
1502        // remove from database
1503
f_defs.db_delete_field_definition (fieldDefID);
1504    }
1505
1506
1507    /**
1508     * Method getTextFileService
1509     *
1510     * @return a JahiaTextFileService instance
1511     */

1512    protected JahiaTextFileService getTextFileService () {
1513
1514        return ServicesRegistry.getInstance ().getJahiaTextFileService ();
1515    }
1516
1517    //-------------------------------------------------------------------------
1518
private boolean logMe (JahiaField theField) {
1519        boolean out = false;
1520        int ctnid = theField.getctnid ();
1521        if (ctnid > 0) {
1522            ServicesRegistry sReg = ServicesRegistry.getInstance ();
1523            if (sReg != null) {
1524                JahiaContainersService ctnSrv = sReg.getJahiaContainersService ();
1525                if (ctnSrv != null) {
1526                    try {
1527                        JahiaContainer container = ctnSrv.loadContainerInfo (ctnid,
1528                                EntryLoadRequest.STAGED);
1529                        if (container != null) {
1530                            String JavaDoc containerName = container.getDefinition ().getName ();
1531                            if (!containerName.equals ("PortletList")) {
1532                                out = true;
1533                            }
1534                        }
1535                    } catch (JahiaException je) {
1536                        // do nothing
1537
}
1538                }
1539            }
1540        }
1541        return out;
1542    }
1543
1544    //--------------------------------------------------------------------------
1545
/**
1546     * returns a DOM representation of all fields of a site
1547     *
1548     * @param siteID
1549     */

1550    public JahiaDOMObject getFieldsAsDOM (int siteID) throws JahiaException {
1551
1552        return fieldsDB.getFieldsAsDOM (siteID);
1553
1554    }
1555
1556
1557    //--------------------------------------------------------------------------
1558
/**
1559     * returns a DOM representation of all field def of a site
1560     *
1561     * @param siteID
1562     */

1563    public JahiaDOMObject getFieldDefsAsDOM (int siteID) throws JahiaException {
1564
1565        return f_defs.getFieldDefsAsDOM (siteID);
1566
1567    }
1568
1569
1570    //--------------------------------------------------------------------------
1571
/**
1572     * returns a DOM representation of all field def props of a site
1573     *
1574     * @param siteID
1575     */

1576    public JahiaDOMObject getFieldDefPropsAsDOM (int siteID) throws JahiaException {
1577
1578        return f_defs.getFieldDefPropsAsDOM (siteID);
1579
1580    }
1581
1582    //--------------------------------------------------------------------------
1583
/**
1584     * Returns a vector of all Acl ID used by fields for a site
1585     * Need this for site extraction
1586     *
1587     * @param siteID
1588     */

1589    public Vector JavaDoc getAclIDs (int siteID)
1590            throws JahiaException {
1591        return f_utils.db_get_all_acl_id (siteID);
1592    }
1593
1594
1595    /**
1596     * Creates a JahiaField from a Content field.
1597     *
1598     * @param contentField the content field source
1599     * state for which to construct the JahiaField
1600     *
1601     * @return a JahiaField corresponding to the language, workflow state and
1602     * eventually version ID specified in the EntryLoadRequest object inside
1603     * the ParamBean object.
1604     *
1605     * @throws JahiaException in case we have trouble loading or accessing the
1606     * entry state of the content field.
1607     */

1608    public JahiaField contentFieldToJahiaField (
1609            ContentField contentField,
1610            EntryLoadRequest entryLoadRequest)
1611            throws JahiaException {
1612
1613        logger.debug ("Making JahiaField facade for field " + contentField.getID ());
1614
1615        ContentObjectEntryState entryState =
1616                contentField.getEntryState (entryLoadRequest);
1617
1618        if (entryState == null) {
1619            logger.debug (
1620                    "Entry state " + entryLoadRequest + " not found for field " + contentField.getID () + ", returning null field !");
1621            return null;
1622        }
1623        JahiaField jahiaField = createJahiaField (
1624                contentField.getID (),
1625                contentField.getSiteID (),
1626                contentField.getPageID (),
1627                contentField.getContainerID (),
1628                contentField.getFieldDefID (),
1629                contentField.getType (),
1630                contentField.getConnectType (),
1631                contentField.getDBValue (entryState),
1632                0, // ranking in field is deprecated.
1633
contentField.getAclID (),
1634                entryState.getVersionID (),
1635                entryState.getWorkflowState (),
1636                entryState.getLanguageCode ());
1637
1638        logger.debug (
1639                "Returning JahiaField facade for field " + contentField.getID () + " using language code=" + jahiaField.getLanguageCode ());
1640
1641        return jahiaField;
1642    }
1643
1644    public void serializeNonContainerFieldsToXML (XmlWriter xmlWriter,
1645                                                  XMLSerializationOptions
1646            xmlSerializationOptions,
1647                                                  int pageID,
1648                                                  ParamBean paramBean)
1649            throws IOException JavaDoc {
1650        try {
1651            Vector JavaDoc fieldIDs = f_utils.db_get_only_active_non_container_field_ids_in_page (
1652                    pageID);
1653
1654            // for each field, we check if the user has write+admin access to it,
1655
// if so we can validate it
1656
for (int i = 0; i < fieldIDs.size (); i++) {
1657                int id = ((Integer JavaDoc) fieldIDs.elementAt (i)).intValue ();
1658
1659                ContentField theField = ContentField.getField (id);
1660                theField.serializeToXML (xmlWriter, xmlSerializationOptions, paramBean);
1661            }
1662        } catch (JahiaException je) {
1663
1664        }
1665
1666    }
1667
1668    /**
1669     * Compose the file absolute path to a flat file containing the default value for a field definition.
1670     *
1671     * @param siteID
1672     * @param name
1673     *
1674     * @return
1675     */

1676    public String JavaDoc composeFieldDefDefaultValueFilePath (int siteID, String JavaDoc name) {
1677        StringBuffer JavaDoc buff = new StringBuffer JavaDoc (Jahia.getSettings ().getJahiaVarDiskPath ());
1678        buff.append (File.separator);
1679        buff.append ("field_definitions");
1680        buff.append (File.separator);
1681        buff.append (siteID);
1682        buff.append ("_");
1683        buff.append (name);
1684        buff.append ("_defaultvalue.txt");
1685        return buff.toString ();
1686    }
1687
1688    /**
1689     * Invalidates a JahiaField cache entry.
1690     * @param fieldID the identifier for the field entry to invalidate in the
1691     * cache.
1692     */

1693    public void invalidateCacheField (int fieldID) {
1694        //cacheFields.remove(getCacheFieldActiveEntryKey(fieldID));
1695
//cacheFields.remove(getCacheFieldStagingEntryKey(fieldID));
1696
ContentField.removeFromCache(fieldID);
1697    }
1698
1699    /**
1700     * reset the page preloaded fields status , so that the preloading operation
1701     * can be performed again the next page access
1702     *
1703     * @param pageId int
1704     */

1705    public void allowFieldsPreloadingForPage(int pageId){
1706        ContentFieldDB.getInstance().allowFieldsPreloadingForPage(pageId);
1707    }
1708
1709    private void createFileDefinitionRepository () {
1710
1711        StringBuffer JavaDoc buff =
1712                new StringBuffer JavaDoc (Jahia.getSettings ().getJahiaVarDiskPath ());
1713        buff.append (File.separator);
1714        buff.append ("field_definitions");
1715        File JavaDoc f = new File JavaDoc (buff.toString ());
1716        f.mkdir ();
1717    }
1718
1719    private String JavaDoc checkFieldEnumerationValues (String JavaDoc fieldValue) {
1720        String JavaDoc value = fieldValue;
1721        if (fieldValue != null
1722                && (fieldValue.toLowerCase ().startsWith ("<jahia_multivalue"))) {
1723            value = "";
1724            int pos = fieldValue.indexOf ("[");
1725            if (pos != -1) {
1726                int pos2 = fieldValue.indexOf ("]>");
1727                if (pos2 != -1) {
1728                    value = fieldValue.substring (pos2 + 2, fieldValue.length ());
1729                }
1730            }
1731        }
1732        return value;
1733    }
1734}
1735
Popular Tags