KickJava   Java API By Example, From Geeks To Geeks.

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


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  * 09-AUG-2003, Jahia Solutions Sarl, Fulco Houkes
37  *
38  * ----- END LICENSE BLOCK -----
39  */

40
41
42 package org.jahia.services.fields;
43
44 import java.sql.Connection JavaDoc;
45 import java.sql.PreparedStatement JavaDoc;
46 import java.sql.ResultSet JavaDoc;
47 import java.sql.SQLException JavaDoc;
48 import java.sql.Statement JavaDoc;
49 import java.util.HashMap JavaDoc;
50 import java.util.Hashtable JavaDoc;
51 import java.util.Map JavaDoc;
52 import java.util.Vector JavaDoc;
53
54 import org.apache.log4j.Logger;
55 import org.jahia.exceptions.JahiaException;
56 import org.jahia.exceptions.JahiaInitializationException;
57 import org.jahia.services.cache.Cache;
58 import org.jahia.services.cache.CacheFactory;
59 import org.jahia.services.database.ConnectionDispenser;
60 import org.jahia.services.version.ContentObjectEntryState;
61 import org.jahia.services.version.EntryLoadRequest;
62 import org.jahia.services.version.EntryStateable;
63 import org.jahia.utils.JahiaTools;
64
65
66 /**
67  * This class contains DB Tools used by ContentField and ContentFieldTool to access the database
68  */

69 class ContentFieldDB {
70
71     private static Logger logger = Logger.getLogger (ContentFieldDB.class);
72
73     /** unique singleton instance */
74     private static ContentFieldDB instance = null;
75
76     // the preloaded page cache.
77
public static final String JavaDoc PRELOADED_PAGE_CACHE = "PreloadedPageCache";
78
79     /** Already preloaded page cache */
80     private static Cache preloadedPagesCache;
81
82     /**
83      * Return the unique instance of this class
84      *
85      * @return the unique instance of this class
86      */

87     public static synchronized ContentFieldDB getInstance () {
88         if (instance == null) {
89             instance = new ContentFieldDB ();
90
91             try {
92                 preloadedPagesCache = CacheFactory
93                     .createCache (PRELOADED_PAGE_CACHE);
94             } catch (JahiaInitializationException e) {
95                 logger.warn (e);
96             }
97         }
98         return instance;
99     }
100
101 /////////////// BELOW ARE DATABASE ACCESS RELATED METHODS /////////////////
102

103     /**
104      * Loads a ContentField from the Database.
105      * A content field holds at least the list of the data that is in the
106      * database for ACTIVE and STAGED states, and every language, but in this
107      * method, no VALUE is loaded at all.
108      * An exception is triggered if the field doesn't exist of if any error
109      * occur during loading process.
110      *
111      * @throws JahiaException If the field doesn't exist, or there's a DB error
112      * @todo include PROPERTIES LOAD ! FIXME
113      */

114     protected ContentField loadContentFieldDB (int fieldID) throws JahiaException {
115         ContentField theField = null;
116         Connection JavaDoc dbConn = null;
117         PreparedStatement JavaDoc stmt = null;
118         ResultSet JavaDoc rs = null;
119
120         final String JavaDoc selectFields = "jahiaid_jahia_fields_data,pageid_jahia_fields_data,ctnid_jahia_fields_data,fielddefid_jahia_fields_data,type_jahia_fields_data,connecttype_jahia_fields_data,value_jahia_fields_data,rights_jahia_fields_data,version_id,workflow_state,language_code";
121
122         try {
123             // We first try to get all ACTIVE & STAGED fields, but this query
124
// won't give anything if the Field doesn't exist anymore (versioning)
125
String JavaDoc sqlQuery = "SELECT " +
126                     selectFields +
127                     " FROM jahia_fields_data WHERE id_jahia_fields_data=? AND workflow_state>=1";
128
129             dbConn = ConnectionDispenser.getConnection ();
130             stmt = dbConn.prepareStatement (sqlQuery);
131             stmt.setInt (1, fieldID);
132             // rs can't be null (cf. api)
133
rs = stmt.executeQuery ();
134
135             // is there at least one element in the resultset ?
136
if (rs.next ()) {
137                 // yes, we get first value
138
int jahiaID = rs.getInt (1);
139                 int pageID = rs.getInt (2);
140                 int ctnid = rs.getInt (3);
141                 int fieldDefID = rs.getInt (4);
142                 int typeField = rs.getInt (5);
143                 int connectType = rs.getInt (6);
144                 String JavaDoc fieldValue = rs.getString (7);
145                 if (fieldValue == null) {
146                     // this ugly hack is necessary because Oracle is incapable of
147
// distinguishing between NULL and empty string values.
148
fieldValue = org.jahia.data.constants.JahiaConstants.NULL_STRING_MARKER;
149                 }
150                 int rights = rs.getInt (8);
151                 int versionID = rs.getInt (9);
152                 int versionStatus = rs.getInt (10);
153                 String JavaDoc languageCode = rs.getString (11);
154
155                 Vector JavaDoc activeAndStagedVersions = new Vector JavaDoc ();
156                 Hashtable JavaDoc activeAndStagedDBValues = new Hashtable JavaDoc ();
157                 ContentObjectEntryState curEntryState = new ContentObjectEntryState (
158                         versionStatus, versionID, languageCode);
159                 activeAndStagedVersions.add (curEntryState);
160                 activeAndStagedDBValues.put (curEntryState, fieldValue);
161
162                 // then we're only interested by the different version, active and lang values
163
// (the rest remains the same)
164
while (rs.next ()) {
165                     fieldValue = rs.getString (7);
166                     if (fieldValue == null) {
167                         // this ugly hack is necessary because Oracle is incapable of
168
// distinguishing between NULL and empty string values.
169
fieldValue =
170                                 org.jahia.data.constants.JahiaConstants.NULL_STRING_MARKER;
171                     }
172                     versionID = rs.getInt (9);
173                     versionStatus = rs.getInt (10);
174                     languageCode = rs.getString (11);
175                     curEntryState =
176                             new ContentObjectEntryState (versionStatus, versionID,
177                                     languageCode);
178                     activeAndStagedVersions.add (curEntryState);
179                     activeAndStagedDBValues.put (curEntryState, fieldValue);
180                 }
181
182                 theField =
183                         ContentFieldTools.getInstance ().
184                         createContentFieldInstance (
185                                 fieldID, jahiaID, pageID, ctnid, fieldDefID, typeField,
186                                 connectType, rights, activeAndStagedVersions,
187                                 activeAndStagedDBValues);
188             } else
189             // no element found in resultset, it means that the field is deleted (but maybe exist in
190
// an inactive version!) or it doesn't exist at all (trigers an exception then)
191
{
192                 // we try loading an old version
193
sqlQuery = "SELECT " +
194                         selectFields +
195                         " FROM jahia_fields_data WHERE id_jahia_fields_data=?";
196
197                 rs.close();
198                 stmt.close();
199                 stmt = dbConn.prepareStatement (sqlQuery);
200                 stmt.setInt (1, fieldID);
201                 rs = stmt.executeQuery ();
202
203                 // yes an inactive field does exist, we create the ContentField
204
if (rs.next ()) {
205                     int jahiaID = rs.getInt ("jahiaid_jahia_fields_data");
206                     int pageID = rs.getInt ("pageid_jahia_fields_data");
207                     int ctnid = rs.getInt ("ctnid_jahia_fields_data");
208                     int fieldDefID = rs.getInt ("fielddefid_jahia_fields_data");
209                     int typeField = rs.getInt ("type_jahia_fields_data");
210                     int connectType = rs.getInt ("connecttype_jahia_fields_data");
211                     int rights = rs.getInt ("rights_jahia_fields_data");
212                     theField = ContentFieldTools.getInstance ().
213                             createContentFieldInstance (
214                                     fieldID, jahiaID, pageID, ctnid, fieldDefID, typeField,
215                                     connectType, rights, new Vector JavaDoc (), new Hashtable JavaDoc ());
216                 } else
217                 // oops the field doesn't exist at all, let's trigger an exception!
218
{
219                     throw new JahiaException
220                             ("Field " + fieldID + " not found in database!",
221                                     "Field " + fieldID + " not found in database!",
222                                     JahiaException.DATABASE_ERROR,
223                                     JahiaException.ERROR_SEVERITY);
224                 }
225             }
226
227         } catch (SQLException JavaDoc se) {
228             throw new JahiaException ("Cannot load field " + fieldID + "from the database",
229                     se.getMessage (), JahiaException.DATABASE_ERROR,
230                     JahiaException.ERROR_SEVERITY, se);
231         } finally {
232             closeStatement(stmt);
233         }
234
235         return theField;
236     }
237
238     /**
239      * Preloads all the active or staged fields for a given page into a specified
240      * field cache.
241      *
242      * @param pageID the page ID for which to preload all the content fields
243      * @param fieldCache the field cache in which to insert the loaded fields.
244      *
245      * @throws JahiaException thrown if there was an error while loading the fields from the database.
246      */

247     protected void preloadActiveOrStagedFieldsByPageID (int pageID, Cache fieldCache)
248             throws JahiaException {
249         ContentField theField = null;
250         Connection JavaDoc dbConn = null;
251         PreparedStatement JavaDoc stmt = null;
252         ResultSet JavaDoc rs = null;
253
254         // check if the page has been already preloaded or not
255
if ( preloadedPagesCache.containsKey(new Integer JavaDoc(pageID)) ){
256             return;
257         }
258
259         final String JavaDoc selectFields =
260                 "id_jahia_fields_data,jahiaid_jahia_fields_data,ctnid_jahia_fields_data,fielddefid_jahia_fields_data,type_jahia_fields_data,connecttype_jahia_fields_data,value_jahia_fields_data,rights_jahia_fields_data,version_id,workflow_state,language_code";
261
262         try {
263             // We first try to get all ACTIVE & STAGED fields, but this query
264
// won't give anything if the Field doesn't exist anymore (versioning)
265
final String JavaDoc sqlQuery = "SELECT " +
266                     selectFields +
267                     " FROM jahia_fields_data WHERE pageid_jahia_fields_data=? AND workflow_state>=1 ORDER BY id_jahia_fields_data";
268
269             dbConn = org.jahia.services.database.ConnectionDispenser.getConnection ();
270             stmt = dbConn.prepareStatement (sqlQuery);
271             stmt.setInt (1, pageID);
272             // rs can't be null (cf. api)
273
rs = stmt.executeQuery ();
274
275             if (rs.next ()) {
276
277                 Vector JavaDoc activeAndStagedVersions = new Vector JavaDoc ();
278                 Hashtable JavaDoc activeAndStagedDBValues = new Hashtable JavaDoc ();
279
280                 // first row is a special case...
281
int fieldID = rs.getInt (1);
282                 int jahiaID = rs.getInt (2);
283                 int ctnID = rs.getInt (3);
284                 int fieldDefID = rs.getInt (4);
285                 int typeField = rs.getInt (5);
286                 int connectType = rs.getInt (6);
287                 String JavaDoc fieldValue = rs.getString (7);
288                 if (fieldValue == null) {
289                     // this ugly hack is necessary because Oracle is incapable of
290
// distinguishing between NULL and empty string values.
291
fieldValue = org.jahia.data.constants.JahiaConstants.NULL_STRING_MARKER;
292                 }
293                 int rights = rs.getInt (8);
294                 int versionID = rs.getInt (9);
295                 int versionStatus = rs.getInt (10);
296                 String JavaDoc languageCode = rs.getString (11);
297
298                 ContentObjectEntryState curEntryState = new ContentObjectEntryState (
299                         versionStatus, versionID, languageCode);
300                 activeAndStagedVersions.add (curEntryState);
301                 activeAndStagedDBValues.put (curEntryState, fieldValue);
302
303                 while (rs.next ()) {
304
305                     int newFieldID = rs.getInt (1);
306                     int newJahiaID = rs.getInt (2);
307                     int newCtnID = rs.getInt (3);
308                     int newFieldDefID = rs.getInt (4);
309                     int newTypeField = rs.getInt (5);
310                     int newConnectType = rs.getInt (6);
311                     String JavaDoc newFieldValue = rs.getString (7);
312                     int newRights = rs.getInt (8);
313                     int newVersionID = rs.getInt (9);
314                     int newVersionStatus = rs.getInt (10);
315                     String JavaDoc newLanguageCode = rs.getString (11);
316
317                     if (fieldID != newFieldID) {
318                         theField =
319                                 ContentFieldTools.getInstance ().
320                                 createContentFieldInstance (
321                                         fieldID, jahiaID, pageID, ctnID, fieldDefID,
322                                         typeField,
323                                         connectType, rights, activeAndStagedVersions,
324                                         activeAndStagedDBValues);
325                         // PAP: Check added to prevent cache timeouts. Maybe we should check, whether the
326
// cached entry is older than theField (???)
327
if (!fieldCache.containsKey(new Integer JavaDoc (fieldID))){
328                           fieldCache.put (new Integer JavaDoc (fieldID), theField);
329                         }
330                         activeAndStagedVersions = new Vector JavaDoc ();
331                         activeAndStagedDBValues = new Hashtable JavaDoc ();
332                     }
333
334                     fieldID = newFieldID;
335                     jahiaID = newJahiaID;
336                     ctnID = newCtnID;
337                     fieldDefID = newFieldDefID;
338                     typeField = newTypeField;
339                     connectType = newConnectType;
340                     fieldValue = newFieldValue;
341                     if (fieldValue == null) {
342                         // this ugly hack is necessary because Oracle is incapable of
343
// distinguishing between NULL and empty string values.
344
fieldValue =
345                                 org.jahia.data.constants.JahiaConstants.NULL_STRING_MARKER;
346                     }
347                     rights = newRights;
348
349                     curEntryState =
350                             new ContentObjectEntryState (newVersionStatus, newVersionID,
351                                     newLanguageCode);
352                     activeAndStagedVersions.add (curEntryState);
353                     activeAndStagedDBValues.put (curEntryState, fieldValue);
354                 }
355             }
356             ContentFieldDB.preloadedPagesCache.put(new Integer JavaDoc(pageID),new Integer JavaDoc(pageID));
357
358         } catch (SQLException JavaDoc se) {
359             throw new JahiaException (
360                     "Cannot preload fields for page " + pageID + "from the database",
361                     se.getMessage (), JahiaException.DATABASE_ERROR,
362                     JahiaException.ERROR_SEVERITY, se);
363         } finally {
364             closeStatement(stmt);
365         }
366
367     }
368
369     /**
370      * Preloads all the active or staged fields for a given container into a
371      * specified field cache.
372      *
373      * @param containerID the container ID for which to preload all the content fields
374      * @param fieldCache the field cache in which to insert the loaded fields.
375      *
376      * @throws JahiaException thrown if there was an error while loading the
377      * fields from the database.
378      */

379     protected void preloadActiveOrStagedFieldsByContainerID (int containerID, Cache fieldCache)
380             throws JahiaException {
381         ContentField theField = null;
382         Connection JavaDoc dbConn = null;
383         PreparedStatement JavaDoc stmt = null;
384         ResultSet JavaDoc rs = null;
385
386         final String JavaDoc selectFields =
387                 "id_jahia_fields_data,jahiaid_jahia_fields_data,pageid_jahia_fields_data,fielddefid_jahia_fields_data,type_jahia_fields_data,connecttype_jahia_fields_data,value_jahia_fields_data,rights_jahia_fields_data,version_id,workflow_state,language_code";
388
389         try {
390             // We first try to get all ACTIVE & STAGED fields, but this query
391
// won't give anything if the Field doesn't exist anymore (versioning)
392
final String JavaDoc sqlQuery = "SELECT " +
393                     selectFields +
394                     " FROM jahia_fields_data WHERE ctnid_jahia_fields_data=? AND workflow_state>=1 ORDER BY id_jahia_fields_data";
395
396             dbConn = org.jahia.services.database.ConnectionDispenser.getConnection ();
397             stmt = dbConn.prepareStatement (sqlQuery);
398             stmt.setInt (1, containerID);
399             // rs can't be null (cf. api)
400
rs = stmt.executeQuery ();
401
402             if (rs.next ()) {
403
404                 Vector JavaDoc activeAndStagedVersions = new Vector JavaDoc ();
405                 Hashtable JavaDoc activeAndStagedDBValues = new Hashtable JavaDoc ();
406
407                 // first row is a special case...
408
int fieldID = rs.getInt (1);
409                 int jahiaID = rs.getInt (2);
410                 int pageID = rs.getInt (3);
411                 int fieldDefID = rs.getInt (4);
412                 int typeField = rs.getInt (5);
413                 int connectType = rs.getInt (6);
414                 String JavaDoc fieldValue = rs.getString (7);
415                 if (fieldValue == null) {
416                     // this ugly hack is necessary because Oracle is incapable of
417
// distinguishing between NULL and empty string values.
418
fieldValue = org.jahia.data.constants.JahiaConstants.NULL_STRING_MARKER;
419                 }
420                 int rights = rs.getInt (8);
421                 int versionID = rs.getInt (9);
422                 int versionStatus = rs.getInt (10);
423                 String JavaDoc languageCode = rs.getString (11);
424
425                 ContentObjectEntryState curEntryState = new ContentObjectEntryState (
426                         versionStatus, versionID, languageCode);
427                 activeAndStagedVersions.add (curEntryState);
428                 activeAndStagedDBValues.put (curEntryState, fieldValue);
429
430                 while (rs.next ()) {
431
432                     int newFieldID = rs.getInt (1);
433                     int newJahiaID = rs.getInt (2);
434                     int newPageID = rs.getInt (3);
435                     int newFieldDefID = rs.getInt (4);
436                     int newTypeField = rs.getInt (5);
437                     int newConnectType = rs.getInt (6);
438                     String JavaDoc newFieldValue = rs.getString (7);
439                     int newRights = rs.getInt (8);
440                     int newVersionID = rs.getInt (9);
441                     int newVersionStatus = rs.getInt (10);
442                     String JavaDoc newLanguageCode = rs.getString (11);
443
444                     if (fieldID != newFieldID) {
445                         theField =
446                                 ContentFieldTools.getInstance ().
447                                 createContentFieldInstance (
448                                         fieldID, jahiaID, pageID, containerID, fieldDefID,
449                                         typeField,
450                                         connectType, rights, activeAndStagedVersions,
451                                         activeAndStagedDBValues);
452                         fieldCache.put (new Integer JavaDoc (fieldID), theField);
453                         activeAndStagedVersions = new Vector JavaDoc ();
454                         activeAndStagedDBValues = new Hashtable JavaDoc ();
455                     }
456
457                     fieldID = newFieldID;
458                     jahiaID = newJahiaID;
459                     pageID = newPageID;
460                     fieldDefID = newFieldDefID;
461                     typeField = newTypeField;
462                     connectType = newConnectType;
463                     fieldValue = newFieldValue;
464                     if (fieldValue == null) {
465                         // this ugly hack is necessary because Oracle is incapable of
466
// distinguishing between NULL and empty string values.
467
fieldValue =
468                                 org.jahia.data.constants.JahiaConstants.NULL_STRING_MARKER;
469                     }
470                     rights = newRights;
471
472                     curEntryState =
473                             new ContentObjectEntryState (newVersionStatus, newVersionID,
474                                     newLanguageCode);
475                     activeAndStagedVersions.add (curEntryState);
476                     activeAndStagedDBValues.put (curEntryState, fieldValue);
477                 }
478             }
479
480         } catch (SQLException JavaDoc se) {
481             throw new JahiaException (
482                     "Cannot preload fields for page " + containerID + "from the database",
483                     se.getMessage (), JahiaException.DATABASE_ERROR,
484                     JahiaException.ERROR_SEVERITY, se);
485         } finally {
486             closeStatement(stmt);
487         }
488
489     }
490
491
492     /**
493      * Load all the BACKUPED entry states (status < 1) and put them directly
494      * into the versioningEntryState vector of the field
495      *
496      * @throws JahiaException if field doesn't exist or there's a DB error.
497      */

498     protected Vector JavaDoc loadOldEntryStates (ContentField theField) throws JahiaException {
499         Connection JavaDoc dbConn = null;
500         PreparedStatement JavaDoc stmt = null;
501         ResultSet JavaDoc rs = null;
502         Vector JavaDoc result = null;
503
504         try {
505             String JavaDoc sqlQuery = "SELECT version_id,workflow_state,language_code FROM jahia_fields_data WHERE id_jahia_fields_data=?" +
506                     " AND workflow_state<1";
507             dbConn = org.jahia.services.database.ConnectionDispenser.getConnection ();
508             stmt = dbConn.prepareStatement (sqlQuery);
509             stmt.setInt(1, theField.getID ());
510             // rs can't be null
511
rs = stmt.executeQuery ();
512
513             result = new Vector JavaDoc ();
514             while (rs.next ()) {
515                 // and we add the values
516
int versionID = rs.getInt ("version_id");
517                 int workflowState = rs.getInt ("workflow_state");
518                 String JavaDoc languageCode = rs.getString ("language_code");
519                 result.add (
520                         new ContentObjectEntryState (workflowState, versionID, languageCode));
521             }
522
523         } catch (SQLException JavaDoc se) {
524             throw new JahiaException ("Cannot load backuped fields from the database",
525                     se.getMessage (), JahiaException.DATABASE_ERROR,
526                     JahiaException.ERROR_SEVERITY);
527         } finally {
528             closeStatement(stmt);
529         }
530         return result;
531     }
532
533     /**
534      * Loads the Value of a ContentField given it's entry state. Note
535      * that the entry state must contain the exact entry state
536      * as it is stored in the db.
537      * To be called only by a ContentField !
538      *
539      * @throws JahiaException if field doesn't exist, or this field
540      * entry doesn't exist, or there's a DB error.
541      */

542     protected String JavaDoc loadDBValue (ContentField theField,
543                                   ContentObjectEntryState entryState)
544             throws JahiaException {
545         String JavaDoc theValue = null;
546         Connection JavaDoc dbConn = null;
547         PreparedStatement JavaDoc stmt = null;
548         ResultSet JavaDoc rs = null;
549         int workflowState = entryState.getWorkflowState ();
550         try {
551             // We first try to get all ACTIVE & STAGED fields, but this query
552
// won't give anything if the Field doesn't exist anymore (versioning)
553
/*
554             String sqlQuery = "SELECT value_jahia_fields_data FROM jahia_fields_data WHERE "+
555                               "id_jahia_fields_data="+ theField.getID() +" AND "+
556                               "workflow_state="+ entryState.getWorkflowState() +" AND "+
557                               "version_id="+ entryState.getVersionID() +" AND "+
558                               "language_code='"+ entryState.getLanguageCode() + "'";
559             */

560             StringBuffer JavaDoc sqlQuery = new StringBuffer JavaDoc (
561                     "SELECT value_jahia_fields_data FROM jahia_fields_data WHERE ");
562             sqlQuery.append ("id_jahia_fields_data=?");
563             sqlQuery.append (" AND ");
564             if (workflowState > EntryLoadRequest.ACTIVE_WORKFLOW_STATE) {
565                 sqlQuery.append ("workflow_state>");
566                 sqlQuery.append (EntryLoadRequest.ACTIVE_WORKFLOW_STATE);
567             } else if (workflowState == EntryLoadRequest.VERSIONED_WORKFLOW_STATE) {
568                 sqlQuery.append (" ( workflow_state=");
569                 sqlQuery.append (ContentObjectEntryState.WORKFLOW_STATE_VERSIONED); // 0
570
sqlQuery.append (" OR workflow_state=");
571                 sqlQuery.append (ContentObjectEntryState.WORKFLOW_STATE_VERSIONING_DELETED); // -1
572
sqlQuery.append (" ) ");
573             } else {
574                 sqlQuery.append ("workflow_state=?");
575             }
576             sqlQuery.append (" AND version_id=?");
577             sqlQuery.append (" AND language_code=?");
578
579             dbConn = org.jahia.services.database.ConnectionDispenser.getConnection ();
580             stmt = dbConn.prepareStatement (sqlQuery.toString ());
581             
582             int index = 1;
583             stmt.setInt(index++, theField.getID ());
584             if (!(workflowState > EntryLoadRequest.ACTIVE_WORKFLOW_STATE) &&
585               !(workflowState == EntryLoadRequest.VERSIONED_WORKFLOW_STATE)) {
586                 stmt.setInt(index++, workflowState);
587               }
588             stmt.setInt(index++, entryState.getVersionID ());
589             stmt.setString(index++, JahiaTools.quote (entryState.getLanguageCode ()));
590                                             
591             // rs can't be null
592
rs = stmt.executeQuery ();
593
594             // is there at least one element in the resultset ?
595
if (rs.next ()) {
596                 // yes, we get first value
597
theValue = rs.getString ("value_jahia_fields_data");
598                 if (theValue == null) {
599                     // this ugly hack is necessary because Oracle is incapable of
600
// distinguishing between NULL and empty string values.
601
theValue = org.jahia.data.constants.JahiaConstants.NULL_STRING_MARKER;
602                 }
603             } else {
604                 throw new JahiaException (
605                         "Entry " + entryState.toString () + " not found for field " + theField.getID () + " using request : [" + sqlQuery.toString () + "]",
606                         "Entry " + entryState.toString () + " not found for field " + theField.getID (),
607                         JahiaException.DATABASE_ERROR,
608                         JahiaException.ERROR_SEVERITY);
609             }
610
611         } catch (SQLException JavaDoc se) {
612             throw new JahiaException ("Cannot load field from the database",
613                     se.getMessage (), JahiaException.DATABASE_ERROR,
614                     JahiaException.ERROR_SEVERITY, se);
615         } finally {
616             closeStatement(stmt);
617         }
618         return theValue;
619     }
620
621     /**
622      * Loads all the Values of a ContentField, including deleted values,
623      * versioned, etc...
624      * To be called only by a ContentField !
625      *
626      * @return a Map containing as the key a ContentFieldEntryState object, and
627      * as value the String containing the value for the field.
628      *
629      * @throws JahiaException if field doesn't exist, or this field
630      * entry doesn't exist, or there's a DB error.
631      */

632     protected Map JavaDoc loadAllDBValues (ContentField theField)
633             throws JahiaException {
634         Connection JavaDoc dbConn = null;
635         PreparedStatement JavaDoc stmt = null;
636         ResultSet JavaDoc rs = null;
637         Map JavaDoc result = new HashMap JavaDoc ();
638         try {
639             StringBuffer JavaDoc sqlQuery = new StringBuffer JavaDoc (
640                     "SELECT value_jahia_fields_data, workflow_state, version_id, language_code FROM jahia_fields_data WHERE ");
641             sqlQuery.append ("id_jahia_fields_data=?");
642             
643             dbConn = org.jahia.services.database.ConnectionDispenser.getConnection ();
644             stmt = dbConn.prepareStatement (sqlQuery.toString ());
645             stmt.setInt(1, theField.getID ());
646             // rs can't be null
647
rs = stmt.executeQuery ();
648
649             // is there at least one element in the resultset ?
650
if (rs.next ()) {
651                 // yes, we get first value
652
String JavaDoc theValue = rs.getString ("value_jahia_fields_data");
653                 if (theValue == null) {
654                     // this ugly hack is necessary because Oracle is incapable of
655
// distinguishing between NULL and empty string values.
656
theValue = org.jahia.data.constants.JahiaConstants.NULL_STRING_MARKER;
657                 }
658                 int workflowState = rs.getInt ("workflow_state");
659                 int versionID = rs.getInt ("version_id");
660                 String JavaDoc languageCode = rs.getString ("language_code");
661                 ContentObjectEntryState entryState = new ContentObjectEntryState (
662                         workflowState, versionID, languageCode);
663                 result.put (entryState, theValue);
664             } else {
665                 throw new JahiaException ("Entries not found for field " +
666                         theField.getID () +
667                         " using request : [" +
668                         sqlQuery.toString () + "]",
669                         "Entries not found for field " +
670                         theField.getID (),
671                         JahiaException.DATABASE_ERROR,
672                         JahiaException.ERROR_SEVERITY);
673             }
674
675         } catch (SQLException JavaDoc se) {
676             throw new JahiaException ("Cannot load field from the database",
677                     se.getMessage (),
678                     JahiaException.DATABASE_ERROR,
679                     JahiaException.ERROR_SEVERITY, se);
680         } finally {
681             closeStatement(stmt);
682         }
683         return result;
684     }
685
686
687     /**
688      * Backups the Value of a ContentField (into an inactive version)
689      *
690      * @param entryState the EntryState of the field to backup
691      *
692      * @return the entry state of the backuped field, null if the field version didn't exist
693      *
694      * @throws JahiaException if there's a DB error.
695      */

696     protected ContentObjectEntryState backupDBValue (ContentField theField,
697                                                      ContentObjectEntryState entryState)
698             throws JahiaException {
699         logger.debug ("Create a wfstatus 0 of the entry " + entryState.toString ());
700
701         Connection JavaDoc dbConn = null;
702         PreparedStatement JavaDoc stmt = null;
703         Statement JavaDoc insertStmt = null;
704         ResultSet JavaDoc rs = null;
705
706         ContentObjectEntryState result = null;
707
708         int fieldID = theField.getID ();
709
710         try {
711             StringBuffer JavaDoc buffer = new StringBuffer JavaDoc("SELECT * FROM jahia_fields_data WHERE ");
712             buffer.append("id_jahia_fields_data = ?");
713             buffer.append(" AND workflow_state=?");
714             buffer.append(" AND version_id=?");
715             buffer.append(" AND language_code=?");
716
717             dbConn = org.jahia.services.database.ConnectionDispenser.getConnection ();
718             stmt = dbConn.prepareStatement (buffer.toString());
719             stmt.setInt(1, fieldID);
720             stmt.setInt(2, entryState.getWorkflowState ());
721             stmt.setInt(3, entryState.getVersionID ());
722             stmt.setString(4, entryState.getLanguageCode ());
723             rs = stmt.executeQuery ();
724             if (rs != null)
725                 if (rs.next ()) {
726                     insertStmt = dbConn.createStatement ();
727                     // add the version to the list of versioning info in the field
728
int versionID = rs.getInt ("version_id");
729                     String JavaDoc languageCode = rs.getString ("language_code");
730                     result = new ContentObjectEntryState (0, versionID, languageCode);
731
732                     buffer = new StringBuffer JavaDoc ("INSERT INTO jahia_fields_data (id_jahia_fields_data,jahiaid_jahia_fields_data,pageid_jahia_fields_data,ctnid_jahia_fields_data,fielddefid_jahia_fields_data,type_jahia_fields_data,connecttype_jahia_fields_data,value_jahia_fields_data,rank_jahia_fields_data,rights_jahia_fields_data,version_id,workflow_state,language_code) VALUES (");
733                     buffer.append(fieldID);
734                     buffer.append( ",");
735                     buffer.append(rs.getInt ("jahiaid_jahia_fields_data"));
736                     buffer.append(",");
737                     buffer.append(rs.getInt ("pageid_jahia_fields_data"));
738                     buffer.append(",");
739                     buffer.append(rs.getInt ("ctnid_jahia_fields_data"));
740                     buffer.append(",");
741                     buffer.append(rs.getInt ("fielddefid_jahia_fields_data"));
742                     buffer.append(",");
743                     buffer.append(rs.getInt ("type_jahia_fields_data"));
744                     buffer.append(",");
745                     buffer.append(rs.getInt ("connecttype_jahia_fields_data"));
746                     buffer.append(",");
747                     buffer.append("'" + JahiaTools.quote (rs.getString ("value_jahia_fields_data")));
748                     buffer.append("',");
749                     buffer.append(rs.getInt ("rank_jahia_fields_data"));
750                     buffer.append(",");
751                     buffer.append(rs.getInt ("rights_jahia_fields_data"));
752                     buffer.append(",");
753                     buffer.append(versionID);
754                     buffer.append(",");
755                     buffer.append("0, ");
756                     buffer.append("'");
757                     buffer.append(languageCode);
758                     buffer.append("')");
759                     insertStmt.execute (buffer.toString());
760                 }
761         } catch (SQLException JavaDoc se) {
762             throw new JahiaException ("Cannot backup field in the database",
763                     se.getMessage (), JahiaException.DATABASE_ERROR,
764                     JahiaException.ERROR_SEVERITY, se);
765         } finally {
766             closeStatement(stmt);
767             closeStatement(insertStmt);
768         }
769         if (result == null) {
770             logger.debug ("The entry wasn't found in DB and therefore wasn't backuped");
771         }
772         return result;
773     }
774
775     /**
776      * creates a new EMPTY version of a field. The versionID is set to 0.
777      */

778     protected void createDBValue (ContentField theField,
779                                   ContentObjectEntryState entryState)
780             throws JahiaException {
781         Connection JavaDoc dbConn = null;
782         Statement JavaDoc stmt = null;
783
784         try {
785             StringBuffer JavaDoc sqlQuery = new StringBuffer JavaDoc (
786                     "INSERT INTO jahia_fields_data (id_jahia_fields_data,jahiaid_jahia_fields_data,pageid_jahia_fields_data,ctnid_jahia_fields_data,fielddefid_jahia_fields_data,type_jahia_fields_data,connecttype_jahia_fields_data,value_jahia_fields_data,rank_jahia_fields_data,rights_jahia_fields_data,version_id,workflow_state,language_code) VALUES (");
787             sqlQuery.append (theField.getID ());
788             sqlQuery.append (",");
789             sqlQuery.append (theField.getSiteID ());
790             sqlQuery.append (",");
791             sqlQuery.append (theField.getPageID ());
792             sqlQuery.append (",");
793             sqlQuery.append (theField.getContainerID ());
794             sqlQuery.append (",");
795             sqlQuery.append (theField.getFieldDefID ());
796             sqlQuery.append (",");
797             sqlQuery.append (theField.getType ());
798             sqlQuery.append (",");
799             sqlQuery.append (theField.getConnectType ());
800             sqlQuery.append (",");
801             sqlQuery.append ("'',"); // TODO : what about field default value ?
802
sqlQuery.append ("0,"); // TODO check for the last
803
sqlQuery.append (theField.getAclID ());
804             sqlQuery.append (",");
805             sqlQuery.append (entryState.getVersionID ());
806             sqlQuery.append (",");
807             sqlQuery.append (entryState.getWorkflowState ());
808             sqlQuery.append (",");
809             sqlQuery.append ("'");
810             sqlQuery.append (entryState.getLanguageCode ());
811             sqlQuery.append ("')");
812
813             dbConn = ConnectionDispenser.getConnection ();
814             stmt = dbConn.createStatement ();
815             stmt.executeUpdate (sqlQuery.toString());
816
817         } catch (SQLException JavaDoc se) {
818             throw new JahiaException ("Cannot create field in database: ID=" + theField.getID () +
819               " version ID=" + entryState.getVersionID() +
820               " workflowstate=" + entryState.getWorkflowState() +
821               " languagecode=" + entryState.getLanguageCode(),
822               se.getMessage (), JahiaException.DATABASE_ERROR,
823               JahiaException.ERROR_SEVERITY, se);
824
825         } finally {
826             closeStatement(stmt);
827         }
828     }
829
830     /**
831      * update the value of one version of a field. Only the value and the versionID are updated.
832      */

833     protected void updateDBValue (ContentField theField,
834                                   ContentObjectEntryState entryState, String JavaDoc value)
835             throws JahiaException {
836         Connection JavaDoc dbConn = null;
837         Statement JavaDoc stmt = null;
838
839         if (value != null && value.length () > 250) {
840             logger.debug ("the value is more than 250 char and would not be inserted in db ");
841             return;
842         }
843         try {
844             String JavaDoc theValue = value;
845             StringBuffer JavaDoc buffer = new StringBuffer JavaDoc ("UPDATE jahia_fields_data SET ");
846             buffer.append("value_jahia_fields_data = '");
847             buffer.append(JahiaTools.quote (theValue));
848             buffer.append("', ");
849             buffer.append("version_id = ");
850             buffer.append(entryState.getVersionID ());
851             buffer.append(" WHERE id_jahia_fields_data = ");
852             buffer.append(theField.getID ());
853             buffer.append(" AND ");
854             buffer.append("workflow_state = ");
855             buffer.append(entryState.getWorkflowState ());
856             buffer.append(" AND ");
857             buffer.append("language_code = '");
858             buffer.append(entryState.getLanguageCode ());
859             buffer.append("'");
860
861             dbConn = ConnectionDispenser.getConnection ();
862             stmt = dbConn.createStatement ();
863             stmt.executeUpdate (buffer.toString());
864         } catch (SQLException JavaDoc se) {
865             throw new JahiaException ("Cannot load field from the database",
866                     se.getMessage (), JahiaException.DATABASE_ERROR,
867                     JahiaException.ERROR_SEVERITY, se);
868         } finally {
869             closeStatement(stmt);
870         }
871     }
872
873     /**
874      * update a version of a field. Only the value and the versionID are updated.
875      *
876      * @param theField The field that is updated
877      * @param oldEntryState The entry state to be updated
878      * @param newEntryState The new value of the entry state
879      */

880     protected void changeDBEntryState (ContentField theField,
881                                        ContentObjectEntryState oldEntryState,
882                                        ContentObjectEntryState newEntryState)
883             throws JahiaException {
884         logger.debug (
885                 "Update from entry " + oldEntryState.toString () + " to new entry " + newEntryState.toString ());
886
887         Connection JavaDoc dbConn = null;
888         Statement JavaDoc stmt = null;
889
890         try {
891             StringBuffer JavaDoc buffer = new StringBuffer JavaDoc("UPDATE jahia_fields_data SET ");
892             buffer.append("workflow_state = ");
893             buffer.append(newEntryState.getWorkflowState ());
894             buffer.append(",");
895             buffer.append("version_id = ");
896             buffer.append(newEntryState.getVersionID ());
897             buffer.append(",");
898             buffer.append("language_code = '");
899             buffer.append(newEntryState.getLanguageCode ());
900             buffer.append("' ");
901             buffer.append("WHERE id_jahia_fields_data = ");
902             buffer.append(theField.getID ());
903             buffer.append(" AND ");
904             buffer.append("workflow_state = ");
905             buffer.append(oldEntryState.getWorkflowState ());
906             buffer.append(" AND ");
907             buffer.append("version_id = ");
908             buffer.append(oldEntryState.getVersionID ());
909             buffer.append(" AND ");
910             buffer.append("language_code = '");
911             buffer.append(oldEntryState.getLanguageCode ());
912             buffer.append("'");
913
914             dbConn = ConnectionDispenser.getConnection ();
915             stmt = dbConn.createStatement ();
916             stmt.executeUpdate (buffer.toString());
917         } catch (SQLException JavaDoc se) {
918             throw new JahiaException (
919                     "Cannot load field from the database to change entry state",
920                     se.getMessage (), JahiaException.DATABASE_ERROR,
921                     JahiaException.ERROR_SEVERITY, se);
922         } finally {
923             closeStatement(stmt);
924         }
925     }
926
927
928     /**
929      * delete a version of an active or staged field. (a version is version status & version language)
930      */

931     protected void deleteDBValue (ContentField theField,
932                                   ContentObjectEntryState entryState)
933             throws JahiaException {
934         logger.debug ("Delete the entry " + entryState.toString ());
935
936         Connection JavaDoc dbConn = null;
937         Statement JavaDoc stmt = null;
938
939         try {
940             StringBuffer JavaDoc buffer = new StringBuffer JavaDoc ("DELETE FROM jahia_fields_data WHERE id_jahia_fields_data=");
941             buffer.append(theField.getID ());
942             buffer.append(" AND workflow_state=");
943             buffer.append(entryState.getWorkflowState ());
944             buffer.append(" AND language_code='");
945             buffer.append(entryState.getLanguageCode ());
946             buffer.append("'");
947             dbConn = ConnectionDispenser.getConnection ();
948             stmt = dbConn.createStatement ();
949             stmt.executeUpdate (buffer.toString());
950         } catch (SQLException JavaDoc se) {
951             throw new JahiaException ("Cannot load field from the database",
952                     se.getMessage (), JahiaException.DATABASE_ERROR,
953                     JahiaException.ERROR_SEVERITY, se);
954         } finally {
955             closeStatement(stmt);
956         }
957     }
958
959     /**
960      * Removes all database data related to a field, including all versions !
961      *
962      * @param fieldID the field identifier to remove all the data in the
963      * field table.
964      */

965     protected void purgeField (int fieldID)
966             throws JahiaException {
967         Connection JavaDoc dbConn = null;
968         PreparedStatement JavaDoc stmt = null;
969
970         try {
971             String JavaDoc sqlQuery = "DELETE FROM jahia_fields_data WHERE id_jahia_fields_data=?";
972             dbConn = ConnectionDispenser.getConnection ();
973             
974             stmt = dbConn.prepareStatement (sqlQuery);
975             stmt.setInt(1, fieldID);
976             stmt.executeUpdate ();
977         } catch (SQLException JavaDoc se) {
978             throw new JahiaException ("Cannot purge field from the database",
979                     se.getMessage (), JahiaException.DATABASE_ERROR,
980                     JahiaException.ERROR_SEVERITY, se);
981         } finally {
982             closeStatement(stmt);
983         }
984     }
985
986     protected void deleteEntry (int fieldID, EntryStateable entryState)
987             throws JahiaException {
988         Connection JavaDoc dbConn = null;
989         PreparedStatement JavaDoc stmt = null;
990
991         try {
992             String JavaDoc sqlQuery =
993                     "DELETE FROM jahia_fields_data WHERE id_jahia_fields_data=? AND workflow_state=? AND version_id=? AND language_code=?";
994             dbConn = ConnectionDispenser.getConnection ();
995             stmt = dbConn.prepareStatement (sqlQuery);
996             stmt.setInt (1, fieldID);
997             stmt.setInt (2, entryState.getWorkflowState ());
998             stmt.setInt (3, entryState.getVersionID ());
999             stmt.setString (4, entryState.getLanguageCode ());
1000            int resultCount = stmt.executeUpdate ();
1001            logger.debug (resultCount + " rows affected by delete of entry");
1002        } catch (SQLException JavaDoc se) {
1003            throw new JahiaException ("Error while deleting entry",
1004                    se.getMessage (),
1005                    JahiaException.DATABASE_ERROR,
1006                    JahiaException.ERROR_SEVERITY, se);
1007        } finally {
1008            closeStatement(stmt);
1009        }
1010    }
1011
1012    /**
1013     * Warning : this method assumes that the destination entry state DOES NOT
1014     * exist in the database. Make sure you do this check before calling this
1015     * method !
1016     *
1017     * @param fieldID the container for which to perform the copy of
1018     * entries
1019     * @param fromEntryState the source entry state
1020     * @param toEntryState the destination entry state (MUST NOT ALREADY EXIST
1021     * IN DATABASE ! an Insert operation is performed here !)
1022     *
1023     * @throws JahiaException raised if there was an error copying the entry
1024     * states, notably if the destination entry state already existed in the
1025     * database and primary keys were in the database.
1026     */

1027    protected void copyEntry (int fieldID,
1028                              EntryStateable fromEntryState,
1029                              EntryStateable toEntryState)
1030            throws JahiaException {
1031
1032        Connection JavaDoc dbConn = null;
1033        PreparedStatement JavaDoc stmt = null;
1034
1035        try {
1036            String JavaDoc sqlQuery =
1037                    "SELECT id_jahia_fields_data,jahiaid_jahia_fields_data,pageid_jahia_fields_data,ctnid_jahia_fields_data,fielddefid_jahia_fields_data,type_jahia_fields_data,connecttype_jahia_fields_data,value_jahia_fields_data,rank_jahia_fields_data,rights_jahia_fields_data,version_id,workflow_state,language_code FROM jahia_fields_data WHERE id_jahia_fields_data=? AND workflow_state=? AND version_id=? AND language_code=?";
1038            dbConn = ConnectionDispenser.getConnection ();
1039            stmt = dbConn.prepareStatement (sqlQuery);
1040            stmt.setInt (1, fieldID);
1041            stmt.setInt (2, fromEntryState.getWorkflowState ());
1042            stmt.setInt (3, fromEntryState.getVersionID ());
1043            stmt.setString (4, fromEntryState.getLanguageCode ());
1044            ResultSet JavaDoc rs = stmt.executeQuery ();
1045            if (rs.next ()) {
1046                int siteID = rs.getInt ("jahiaid_jahia_fields_data");
1047                int pageID = rs.getInt ("pageid_jahia_fields_data");
1048                int ctnID = rs.getInt ("ctnid_jahia_fields_data");
1049                int fieldDefID = rs.getInt ("fielddefid_jahia_fields_data");
1050                int type = rs.getInt ("type_jahia_fields_data");
1051                int connectType = rs.getInt ("connecttype_jahia_fields_data");
1052                String JavaDoc value = rs.getString ("value_jahia_fields_data");
1053                int rank = rs.getInt ("rank_jahia_fields_data");
1054                int rights = rs.getInt ("rights_jahia_fields_data");
1055                stmt.close ();
1056                String JavaDoc insertQuery = "INSERT INTO jahia_fields_data (id_jahia_fields_data,jahiaid_jahia_fields_data,pageid_jahia_fields_data,ctnid_jahia_fields_data,fielddefid_jahia_fields_data,type_jahia_fields_data,connecttype_jahia_fields_data,value_jahia_fields_data,rank_jahia_fields_data,rights_jahia_fields_data,version_id,workflow_state,language_code) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
1057                stmt = dbConn.prepareStatement (insertQuery);
1058                stmt.setInt (1, fieldID);
1059                stmt.setInt (2, siteID);
1060                stmt.setInt (3, pageID);
1061                stmt.setInt (4, ctnID);
1062                stmt.setInt (5, fieldDefID);
1063                stmt.setInt (6, type);
1064                stmt.setInt (7, connectType);
1065                stmt.setString (8, value);
1066                stmt.setInt (9, rank);
1067                stmt.setInt (10, rights);
1068                stmt.setInt (11, toEntryState.getVersionID ());
1069                stmt.setInt (12, toEntryState.getWorkflowState ());
1070                stmt.setString (13, toEntryState.getLanguageCode ());
1071                stmt.executeUpdate ();
1072            }
1073        } catch (SQLException JavaDoc se) {
1074            throw new JahiaException ("Error while copying entry",
1075                    se.getMessage (),
1076                    JahiaException.DATABASE_ERROR,
1077                    JahiaException.ERROR_SEVERITY, se);
1078        } finally {
1079           closeStatement (stmt);
1080        }
1081    }
1082
1083    /**
1084     * Close the specified <code>statement</code>.
1085     *
1086     * @param statement the statement instance to close
1087     */

1088    private void closeStatement(Statement JavaDoc statement) throws JahiaException {
1089        // Close the opened statement
1090
try {
1091            if (statement != null) {
1092                statement.close();
1093            }
1094
1095        } catch (SQLException JavaDoc ex) {
1096            String JavaDoc msg = "Cannot close a statement";
1097            logger.warn (msg, ex);
1098            throw new JahiaException (msg, msg, JahiaException.DATABASE_ERROR,
1099                    JahiaException.CRITICAL_SEVERITY, ex);
1100        }
1101    }
1102
1103    /**
1104     * reset the page preloaded fields status , so that the preloading operation
1105     * can be performed again the next page access
1106     *
1107     * @param pageId int
1108     */

1109    public synchronized void allowFieldsPreloadingForPage(int pageId){
1110        if ( ContentFieldDB.preloadedPagesCache != null ){
1111            ContentFieldDB.preloadedPagesCache.remove(new Integer JavaDoc(pageId));
1112        }
1113    }
1114}
1115
Popular Tags