1 13 package org.jahia.services.version; 14 15 import java.util.ArrayList ; 16 import java.util.Enumeration ; 17 import java.util.HashMap ; 18 import java.util.Iterator ; 19 import java.util.List ; 20 import java.util.ListIterator ; 21 import java.util.Locale ; 22 import java.util.Map ; 23 import java.util.Vector ; 24 25 import org.apache.log4j.Logger; 26 import org.jahia.exceptions.JahiaException; 27 import org.jahia.params.ParamBean; 28 import org.jahia.registries.ServicesRegistry; 29 import org.jahia.services.pages.JahiaPage; 30 import org.jahia.services.sites.JahiaSite; 31 import org.jahia.services.usermanager.JahiaUser; 32 33 34 35 39 public class JahiaVersionDBService extends JahiaVersionService 40 { 41 private static final String SHARED_LANGUAGE = "shared"; 42 private static Logger logger = Logger.getLogger(JahiaVersionDBService.class); 43 44 private static final Locale SHARED_LANG_LOCALE = new Locale (SHARED_LANGUAGE, ""); 45 private static JahiaVersionDBService mInstance; 46 47 54 protected JahiaVersionDBService () throws JahiaException { 55 logger.debug("***** Starting JahiaVersionDBService *****" ); 56 } 57 58 59 66 public static synchronized JahiaVersionDBService getInstance () 67 { 68 if (mInstance == null) 69 { 70 try { 71 mInstance = new JahiaVersionDBService (); 72 } 73 catch (JahiaException ex) { 74 logger.debug("Could not create an instance of the JahiaVersionDBService class", ex); 75 } 76 } 77 return mInstance; 78 } 79 80 84 public boolean isStagingEnabled (int siteID) { 85 86 try 87 { 88 JahiaSite site = ServicesRegistry.getInstance().getJahiaSitesService().getSite(siteID); 89 if ( site==null){ 90 logger.debug("Requested site [" + siteID + "] is null..."); 91 return false; 92 } 93 return site.isStagingEnabled(); 94 } catch (JahiaException je) 95 { 96 logger.debug("Couldn't get staging status...", je); 97 return false; 98 } 99 } 100 101 102 106 public boolean isVersioningEnabled (int siteID) { 107 try { 108 JahiaSite site = ServicesRegistry.getInstance().getJahiaSitesService().getSite(siteID); 109 if ( site==null){ 110 logger.debug("Requested site [" + siteID + "] is null..."); 111 return false; 112 } 113 return site.isVersioningEnabled(); 114 115 } catch (JahiaException je) 116 { 117 logger.debug("Couldn't get versioning status...", je); 118 return false; 119 } 120 } 121 122 125 public int getCurrentVersionID() 126 { 127 java.util.Date d = new java.util.Date (); 128 return (int)(d.getTime() / 1000); 129 } 130 131 134 public JahiaSaveVersion getSiteSaveVersion(int siteID) 135 { 136 boolean staging = false; 137 boolean versioning = false; 138 staging = true; 140 if (isVersioningEnabled (siteID)) versioning = true; 141 142 return new JahiaSaveVersion(staging, versioning); 143 } 144 145 148 public void activateStagedPage ( int pageID, JahiaUser user, ParamBean jParams, StateModificationContext stateModifContext ) 149 throws JahiaException 150 { 151 ServicesRegistry sr = ServicesRegistry.getInstance(); 152 153 JahiaPage thePage = null; 154 thePage = sr.getJahiaPageService().lookupPage(pageID, jParams); 155 if (thePage != null) 156 { 157 int siteID = thePage.getJahiaID(); 158 JahiaSaveVersion saveVersion = getSiteSaveVersion(siteID); 159 ActivationTestResults activationResults = thePage.activeStagingVersion(stateModifContext.getLanguageCodes(), saveVersion, user, jParams, stateModifContext); 160 logger.debug("activation results : " + activationResults.toString()); 161 } 162 } 163 164 165 175 public EntryStateable resolveEntry( Vector entryStateables, EntryLoadRequest loadRequest , boolean ignoreLanguage) 176 { 177 182 EntryStateable result = null; 183 184 List clientLocales = loadRequest.getLocales(); 188 if ( clientLocales.size() == 0 ){ 189 clientLocales.add(0, SHARED_LANG_LOCALE); 191 } 192 Locale sharedLocale = (Locale )clientLocales.get(0); 193 if ( !sharedLocale.toString().equals(SHARED_LANGUAGE) ) 194 { 195 clientLocales.add(0, SHARED_LANG_LOCALE); 196 } 197 ListIterator clientLocalesIter = clientLocales.listIterator(); 198 199 if (loadRequest.isCurrent()) 201 { 202 while (clientLocalesIter.hasNext() && result == null) 203 { 204 Locale currentClientLocale = (Locale ) clientLocalesIter.next(); 205 String langCodeToFind = currentClientLocale.toString(); 206 result = findActiveLanguageEntry(langCodeToFind, entryStateables, ignoreLanguage, loadRequest); 209 if (result == null && !ignoreLanguage 210 && currentClientLocale.getCountry().length() != 0) { 211 langCodeToFind = currentClientLocale.getLanguage(); 214 result = findActiveLanguageEntry(langCodeToFind, entryStateables, ignoreLanguage, loadRequest); 215 } 216 } 217 } else 218 if (loadRequest.getWorkflowState()>EntryLoadRequest.ACTIVE_WORKFLOW_STATE) 220 { 221 while (clientLocalesIter.hasNext() && (result==null)) 222 { 223 Locale currentClientLocale = (Locale ) clientLocalesIter.next(); 224 String langCodeToFind = currentClientLocale.toString(); 225 result = findActiveOrStagingLanguageEntry(langCodeToFind, entryStateables, ignoreLanguage, loadRequest, false); 228 if (result == null && !ignoreLanguage 229 && currentClientLocale.getCountry().length() != 0) { 230 langCodeToFind = currentClientLocale.getLanguage(); 233 result = findActiveOrStagingLanguageEntry(langCodeToFind, entryStateables, ignoreLanguage, loadRequest, false); 234 } 235 236 if ( result != null && 237 (result.getWorkflowState()==EntryLoadRequest.ACTIVE_WORKFLOW_STATE) ){ 238 loadRequest = new EntryLoadRequest(loadRequest); 239 boolean withMarkedForDelete = loadRequest.isWithMarkedForDeletion(); 240 loadRequest.setWithMarkedForDeletion(true); 241 EntryStateable stagedEntry = 243 findActiveOrStagingLanguageEntry(langCodeToFind, 244 entryStateables, 245 ignoreLanguage, 246 loadRequest, true); 247 loadRequest.setWithMarkedForDeletion(withMarkedForDelete); 248 if ( stagedEntry != null && 249 stagedEntry.getWorkflowState()>EntryLoadRequest.ACTIVE_WORKFLOW_STATE 250 && stagedEntry.getVersionID() == EntryLoadRequest.DELETED_WORKFLOW_STATE ){ 251 result = null; 252 } 253 } 254 } 255 } else 256 if (loadRequest.isVersioned()) 258 { 259 int wantedVersionID = loadRequest.getVersionID(); 260 Map lastVersion = new HashMap (); 264 Map deletedVersion = new HashMap (); 265 EntryStateable deletedVer = null; 266 EntryStateable storedVer = null; 267 for (int i=0; i<entryStateables.size(); i++) 268 { 269 EntryStateable thisVer = (EntryStateable)entryStateables.elementAt(i); 270 271 if ( loadRequest.isWithDeleted() && thisVer.getWorkflowState() 273 == EntryLoadRequest.VERSIONED_WORKFLOW_STATE && isDeleted(entryStateables,thisVer.getVersionID()) ){ 274 deletedVer = (EntryStateable)deletedVersion.get(thisVer.getLanguageCode()); 275 if ( deletedVer == null || ( (deletedVer.getLanguageCode().equals(thisVer.getLanguageCode())) 276 && (thisVer.getVersionID()>deletedVer.getVersionID()))){ 277 deletedVersion.put(thisVer.getLanguageCode(), thisVer); 278 } 279 } 280 281 if ((thisVer.getWorkflowState()<=1) && ( (thisVer.getVersionID()<=wantedVersionID || wantedVersionID==0) ) 282 || (thisVer.getWorkflowState() == 1 && loadRequest.getVersionID()==0) ) 283 { 284 storedVer = (EntryStateable)lastVersion.get(thisVer.getLanguageCode()); 285 if ((storedVer==null) || 286 ( (storedVer.getLanguageCode().equals(thisVer.getLanguageCode())) 287 && (thisVer.getVersionID()>storedVer.getVersionID()))) 288 { 289 lastVersion.put(thisVer.getLanguageCode(), thisVer); 290 } 291 } 292 } 293 294 if ( loadRequest.isWithDeleted() ){ 296 Iterator keys = deletedVersion.keySet().iterator(); 297 String lang = null; 298 while (keys.hasNext()){ 299 lang = (String )keys.next(); 300 if (!lastVersion.containsKey(lang)){ 301 lastVersion.put(lang, deletedVersion.get(lang)); 302 } 303 } 304 } 305 306 while (clientLocalesIter.hasNext() && (result==null)) 309 { 310 Locale currentClientLocale = (Locale ) clientLocalesIter.next(); 311 String langCodeToFind = currentClientLocale.toString(); 312 EntryStateable thisVer = (EntryStateable)lastVersion.get(langCodeToFind); 313 if ((thisVer!=null) && (thisVer.getWorkflowState()<=0)) { 315 result=thisVer; 316 break; 317 } 318 if (result == null && !ignoreLanguage 319 && currentClientLocale.getCountry().length() != 0) { 320 langCodeToFind = currentClientLocale.getLanguage(); 321 thisVer = (EntryStateable)lastVersion.get(langCodeToFind); 324 if ((thisVer!=null) && (thisVer.getWorkflowState()<=0)) { 326 result=thisVer; 327 break; 328 } 329 } 330 if ( !clientLocalesIter.hasNext() 331 && result == null && ignoreLanguage 332 && lastVersion.size()>0){ 333 result = (EntryStateable)lastVersion.values().iterator().next(); 335 } 336 } 337 if (result == null) { 338 clientLocalesIter = clientLocales.listIterator(); 341 while (clientLocalesIter.hasNext() && (result==null)) 342 { 343 Locale currentClientLocale = (Locale )clientLocalesIter.next(); 344 String langCodeToFind = currentClientLocale.toString(); 345 result = findActiveLanguageEntry(langCodeToFind, 348 entryStateables, ignoreLanguage, loadRequest); 349 if (result == null && !ignoreLanguage 350 && currentClientLocale.getCountry().length() != 0) { 351 langCodeToFind = currentClientLocale.getLanguage(); 354 result = findActiveLanguageEntry(langCodeToFind, 355 entryStateables, ignoreLanguage, loadRequest); 356 } 357 } 358 359 if (result != null) { 363 if (result.getVersionID() > loadRequest.getVersionID()) { 364 result = null; 367 } 368 } 369 } 370 371 } 372 373 if (result == null) { 374 logger.debug("No entry found for entry load request " + 375 loadRequest.toString() + 376 " . Returning null !"); 377 } 378 379 return result; 380 } 381 382 391 public EntryStateable resolveEntry( Vector entryStateables, EntryLoadRequest loadRequest ) 392 { 393 return resolveEntry(entryStateables,loadRequest,false); 394 } 395 396 private EntryStateable findActiveLanguageEntry(String langCodeToFind, 397 Vector entryStateables, boolean ignoreLanguage, 398 EntryLoadRequest loadRequest) { 399 EntryStateable result = null; 400 401 int availableLanguagesEnum = entryStateables.size(); 402 Map deletedVersion = new HashMap (); 403 EntryStateable deletedVer = null; 404 405 for (int i = availableLanguagesEnum - 1; i >= 0; i--) { 406 EntryStateable thisVer = (EntryStateable)entryStateables.get(i); 407 int thisVerWorkflowState = thisVer.getWorkflowState(); 408 409 int thisVerId = thisVer.getVersionID(); 410 if (thisVerWorkflowState == 1 && (ignoreLanguage 411 || thisVer.getLanguageCode().equals(langCodeToFind))) { 412 result = thisVer; 413 break; 414 } 415 if (loadRequest.isWithDeleted() && thisVerWorkflowState == -1 417 && isDeleted(entryStateables, thisVerId)) { 418 String thisVerLangCode = thisVer.getLanguageCode(); 419 deletedVer = (EntryStateable)deletedVersion.get(thisVerLangCode); 420 if (deletedVer == null 421 || deletedVer.getLanguageCode().equals(thisVerLangCode) 422 && thisVerId > deletedVer.getVersionID()) { 423 deletedVersion.put(thisVerLangCode, thisVer); 424 } 425 } 426 } 427 428 if (result == null && deletedVersion.size() > 0) { 430 result = (EntryStateable)deletedVersion.get(langCodeToFind); 431 if (result == null && ignoreLanguage) { 432 result = (EntryStateable)deletedVersion.values().iterator().next(); 433 } 434 } 435 436 return result; 437 } 438 439 449 private EntryStateable findActiveOrStagingLanguageEntry(String langCodeToFind, 450 Vector entryStateables, boolean ignoreLanguage, 451 EntryLoadRequest loadRequest, boolean stagingOnly) { 452 453 Enumeration availableLanguagesEnum = entryStateables.elements(); 454 EntryStateable activeVer = null; 455 EntryStateable stagedVer = null; 456 while ( (availableLanguagesEnum.hasMoreElements()) ) 457 { 458 460 EntryStateable thisVer = (EntryStateable)availableLanguagesEnum.nextElement(); 461 int thisVerWorkflowState = thisVer.getWorkflowState(); 462 if (thisVerWorkflowState >= EntryLoadRequest.ACTIVE_WORKFLOW_STATE 463 && (ignoreLanguage || thisVer.getLanguageCode().equals(langCodeToFind)) 464 || thisVerWorkflowState == EntryLoadRequest.DELETED_WORKFLOW_STATE 465 && (ignoreLanguage || thisVer.getLanguageCode().equals(langCodeToFind)) 466 && loadRequest.isWithDeleted() && isDeleted(entryStateables, thisVer.getVersionID())) 467 { 468 if (!stagingOnly && thisVerWorkflowState < EntryLoadRequest.STAGING_WORKFLOW_STATE){ 469 if ( activeVer == null ){ 470 activeVer = thisVer; 471 } else if (activeVer.getVersionID()<thisVer.getVersionID()) { 472 activeVer = thisVer; 473 } 474 } else if ( thisVerWorkflowState > EntryLoadRequest.ACTIVE_WORKFLOW_STATE ) { 475 stagedVer = thisVer; 476 } 477 } 478 } 479 480 if ( loadRequest.getWorkflowState()>EntryLoadRequest.ACTIVE_WORKFLOW_STATE ){ 481 483 if (stagedVer != null) { 484 if (loadRequest.isWithMarkedForDeletion()) { 485 return stagedVer; 486 } 487 else if (stagedVer.getVersionID() 488 != EntryLoadRequest.DELETED_WORKFLOW_STATE) { 489 return stagedVer; 490 } 491 } 492 } 493 494 if ( activeVer != null ){ 495 if ( loadRequest.isWithDeleted() ){ 497 return activeVer; 498 } else if ( activeVer.getWorkflowState() 499 != EntryLoadRequest.DELETED_WORKFLOW_STATE ){ 500 return activeVer; 501 } 502 } 503 504 return null; 505 } 506 507 513 private boolean isDeleted(Vector entryStateables, int versionID){ 514 ArrayList entryStates = getClosestVersionedEntryStates(entryStateables, versionID); 515 int size = entryStates.size(); 516 EntryStateable entryState = null; 517 for ( int i=0 ; i<size; i++ ){ 518 entryState = (EntryStateable)entryStates.get(i); 519 if ( entryState.getWorkflowState() != 520 ContentObjectEntryState.WORKFLOW_STATE_VERSIONING_DELETED ){ 521 return false; 522 } 523 } 524 return true; 525 } 526 541 private ArrayList getClosestVersionedEntryStates(Vector entryStateables, int versionID){ 542 543 Map closestInLanguage = new HashMap (); 546 EntryStateable resultEntryState = null; 547 int size = entryStateables.size(); 548 for ( int i=0 ; i<size ; i++ ){ 549 EntryStateable curEntryState = 550 (EntryStateable) entryStateables.get(i); 551 if ( ((curEntryState.getWorkflowState() == ContentObjectEntryState.WORKFLOW_STATE_ACTIVE) && 552 (curEntryState.getVersionID() <= versionID)) 553 || 554 ((curEntryState.getWorkflowState() == ContentObjectEntryState.WORKFLOW_STATE_VERSIONED) && 555 (curEntryState.getVersionID() <= versionID)) 556 || 557 ((curEntryState.getWorkflowState() == ContentObjectEntryState.WORKFLOW_STATE_VERSIONING_DELETED) && 558 (curEntryState.getVersionID() <= versionID)) 559 ) { 560 561 resultEntryState = (EntryStateable) closestInLanguage.get(curEntryState.getLanguageCode()); 566 if (resultEntryState != null) { 567 if (resultEntryState.getVersionID() < 569 curEntryState.getVersionID()) { 570 closestInLanguage.put(curEntryState.getLanguageCode(), curEntryState); 571 } 572 } else { 573 closestInLanguage.put(curEntryState.getLanguageCode(), curEntryState); 575 } 576 } 577 } 578 ArrayList resultEntryStates = new ArrayList (closestInLanguage.values()); 579 return resultEntryStates; 580 } 581 } 582 | Popular Tags |