1 23 package org.infoglue.cms.controllers.kernel.impl.simple; 24 25 import java.text.MessageFormat ; 26 import java.util.ArrayList ; 27 import java.util.Collection ; 28 import java.util.HashSet ; 29 import java.util.Iterator ; 30 import java.util.List ; 31 import java.util.Set ; 32 33 import org.apache.log4j.Logger; 34 import org.exolab.castor.jdo.Database; 35 import org.exolab.castor.jdo.OQLQuery; 36 import org.exolab.castor.jdo.PersistenceException; 37 import org.exolab.castor.jdo.QueryResults; 38 import org.infoglue.cms.entities.content.impl.simple.SmallContentImpl; 39 import org.infoglue.cms.entities.kernel.BaseEntityVO; 40 import org.infoglue.cms.entities.management.ContentTypeDefinitionVO; 41 import org.infoglue.cms.entities.management.LanguageVO; 42 import org.infoglue.cms.exception.SystemException; 43 import org.infoglue.cms.util.CmsPropertyHandler; 44 45 48 public class ExtendedSearchController extends BaseController 49 { 50 private final static Logger logger = Logger.getLogger(ExtendedSearchController.class.getName()); 51 52 55 private static final ExtendedSearchController instance = new ExtendedSearchController(); 56 57 60 private ExtendedSearchController() 61 { 62 super(); 63 } 64 65 68 public static ExtendedSearchController getController() 69 { 70 return instance; 71 } 72 73 76 public Set search(final Integer stateId, final ContentTypeDefinitionVO contentTypeDefinitionVO, final LanguageVO languageVO, final CategoryConditions categories) throws SystemException 77 { 78 final ExtendedSearchCriterias criterias = new ExtendedSearchCriterias(stateId.intValue()); 79 criterias.setContentTypeDefinitions(contentTypeDefinitionVO); 80 criterias.setLanguage(languageVO); 81 criterias.setCategoryConditions(categories); 82 return search(criterias); 83 } 84 85 88 public Set search(final Integer stateId, final ContentTypeDefinitionVO contentTypeDefinitionVO, final LanguageVO languageVO, final CategoryConditions categories, final Database db) throws SystemException 89 { 90 final ExtendedSearchCriterias criterias = new ExtendedSearchCriterias(stateId.intValue()); 91 criterias.setContentTypeDefinitions(contentTypeDefinitionVO); 92 criterias.setLanguage(languageVO); 93 criterias.setCategoryConditions(categories); 94 return search(criterias, db); 95 } 96 97 100 public Set search(final Integer stateId, final List contentTypeDefinitionVOs, final LanguageVO languageVO, final CategoryConditions categories) throws SystemException 101 { 102 final ExtendedSearchCriterias criterias = new ExtendedSearchCriterias(stateId.intValue()); 103 criterias.setContentTypeDefinitions(contentTypeDefinitionVOs); 104 criterias.setLanguage(languageVO); 105 criterias.setCategoryConditions(categories); 106 return search(criterias); 107 } 108 109 112 public Set search(final Integer stateId, final List contentTypeDefinitionVOs, final LanguageVO languageVO, final CategoryConditions categories, final Database db) throws SystemException 113 { 114 final ExtendedSearchCriterias criterias = new ExtendedSearchCriterias(stateId.intValue()); 115 criterias.setContentTypeDefinitions(contentTypeDefinitionVOs); 116 criterias.setLanguage(languageVO); 117 criterias.setCategoryConditions(categories); 118 return search(criterias, db); 119 } 120 121 124 public Set search(final Integer stateId, final ContentTypeDefinitionVO contentTypeDefinitionVO, final LanguageVO languageVO, final CategoryConditions categories, final List xmlAttributes, final String freetext) throws SystemException 125 { 126 final ExtendedSearchCriterias criterias = new ExtendedSearchCriterias(stateId.intValue()); 127 criterias.setContentTypeDefinitions(contentTypeDefinitionVO); 128 criterias.setLanguage(languageVO); 129 criterias.setCategoryConditions(categories); 130 criterias.setFreetext(freetext, xmlAttributes); 131 return search(criterias); 132 } 133 134 137 public Set search(final ExtendedSearchCriterias criterias) throws SystemException 138 { 139 final Database db = beginTransaction(); 140 try 141 { 142 final Set result = search(criterias, db); 143 commitTransaction(db); 144 return result; 145 } 146 catch (Exception e) 147 { 148 rollbackTransaction(db); 149 throw new SystemException(e.getMessage()); 150 } 151 } 152 153 156 public Set search(final ExtendedSearchCriterias criterias, final Database db) throws SystemException 157 { 158 if(criterias == null) 159 return new HashSet (); 160 161 try 162 { 163 final SqlBuilder sqlBuilder = new SqlBuilder(criterias); 164 logger.debug("sql:" + sqlBuilder.getSQL()); 165 166 final OQLQuery oql = db.getOQLQuery(sqlBuilder.getSQL()); 167 for(Iterator i=sqlBuilder.getBindings().iterator(); i.hasNext(); ) 168 { 169 Object o = i.next(); 170 logger.debug("o:" + o.toString()); 171 oql.bind(o); 172 } 173 174 QueryResults results = oql.execute(Database.ReadOnly); 175 Set matchingResults = createResults(results); 176 177 results.close(); 178 oql.close(); 179 180 return matchingResults; 181 } 182 catch(Exception e) 183 { 184 e.printStackTrace(); 185 throw new SystemException(e.getMessage()); 186 } 187 } 188 189 192 private Set createResults(final QueryResults qr) throws PersistenceException, SystemException 193 { 194 final Set results = new HashSet (); 195 while(qr.hasMore()) 196 { 197 results.add(qr.next()); 198 } 199 200 return results; 201 } 202 203 private static Boolean useFull = null; 204 public static boolean useFull() 205 { 206 if(useFull == null) 207 { 208 String useShortTableNames = CmsPropertyHandler.getUseShortTableNames(); 209 if(useShortTableNames == null || !useShortTableNames.equalsIgnoreCase("true")) 210 { 211 useFull = new Boolean (true); 212 } 213 else 214 { 215 useFull = new Boolean (false); 216 } 217 } 218 219 return useFull.booleanValue(); 220 } 221 222 225 public BaseEntityVO getNewVO() 226 { 227 return null; 228 } 229 } 230 231 234 class SqlBuilder 235 { 236 239 private final static Logger logger = Logger.getLogger(SqlBuilder.class.getName()); 240 241 private static final String SELECT_KEYWORD = "SELECT"; 243 private static final String FROM_KEYWORD = "FROM"; 244 private static final String WHERE_KEYWORD = "WHERE"; 245 246 private static final String SPACE = " "; 247 private static final String COMMA = ","; 248 private static final String AND = "AND"; 249 private static final String OR = "OR"; 250 251 private static final String CONTENT_ALIAS = "c"; 253 private static final String CONTENT_VERSION_ALIAS = "cv"; 254 255 private static final String CONTENT_TABLE_SHORT = "cmCont"; 257 private static final String CONTENT_TABLE = "cmContent"; 258 private static final String CONTENT_VERSION_TABLE_SHORT = "cmContVer"; 259 private static final String CONTENT_VERSION_TABLE = "cmContentVersion"; 260 261 private static final String CV_ACTIVE_CLAUSE = CONTENT_VERSION_ALIAS + ".isActive=1"; 263 private static final String CV_LANGUAGE_CLAUSE = CONTENT_VERSION_ALIAS + ".languageId={0}"; 264 private static final String CV_STATE_CLAUSE = CONTENT_VERSION_ALIAS + ".stateId>={0}"; 266 267 private static final String CV_CONTENT_JOIN_SHORT = CONTENT_ALIAS + ".ContId=" + CONTENT_VERSION_ALIAS + ".ContId"; 268 private static final String CV_CONTENT_JOIN = CONTENT_ALIAS + ".contentId=" + CONTENT_VERSION_ALIAS + ".contentId"; 269 private static final String CV_LATEST_VERSION_CLAUSE_SHORT= CONTENT_VERSION_ALIAS + ".ContVerId in (select max(ContVerId) from " + CONTENT_VERSION_TABLE_SHORT + " cv2 where cv2.ContId=" + CONTENT_VERSION_ALIAS + ".ContId AND cv2.languageId={0} AND cv2.stateId>={1} AND cv2.isActive=1)"; 270 private static final String CV_LATEST_VERSION_CLAUSE = CONTENT_VERSION_ALIAS + ".contentVersionId in (select max(contentVersionId) from " + CONTENT_VERSION_TABLE + " cv2 where cv2.contentId=" + CONTENT_VERSION_ALIAS + ".contentId AND cv2.languageId={0} AND cv2.stateId>={1} AND cv2.isActive=1)"; 271 272 private static final String C_CONTENT_TYPE_CLAUSE_SHORT = CONTENT_ALIAS + ".contentTypeDefId={0}"; 273 private static final String C_CONTENT_TYPE_CLAUSE = CONTENT_ALIAS + ".contentTypeDefinitionId={0}"; 274 275 private static final String FREETEXT_EXPRESSION_SHORT = CONTENT_VERSION_ALIAS + ".VerValue like {0}"; 276 private static final String FREETEXT_EXPRESSION = CONTENT_VERSION_ALIAS + ".versionValue like {0}"; 277 278 private static final String FROM_DATE_CLAUSE = CONTENT_ALIAS + ".publishDateTime>={0}"; 279 private static final String TO_DATE_CLAUSE = CONTENT_ALIAS + ".publishDateTime<={0}"; 280 283 private static final String FREETEXT_EXPRESSION_VARIABLE = "%<{0}><![CDATA[%{1}%]]></{0}>%"; 284 285 private final ExtendedSearchCriterias criterias; 286 287 private String sql; 289 private List bindings; 290 291 292 295 public SqlBuilder(final ExtendedSearchCriterias criterias) 296 { 297 super(); 298 this.criterias = criterias; 299 this.bindings = new ArrayList (); 300 301 logger.debug("===[sql]=============================================================="); 302 this.sql = generate(); 303 logger.debug("======================================================================"); 304 logger.debug(sql); 306 logger.debug("===[/sql]============================================================="); 307 } 308 309 312 public String getSQL() 313 { 314 return sql; 315 } 316 317 320 public List getBindings() 321 { 322 return bindings; 323 } 324 325 328 private String generate() 329 { 330 return "CALL SQL" + SPACE + (ExtendedSearchController.useFull() ? generateSelectClause() : generateSelectClauseShort()) + SPACE + generateFromClause() + SPACE + generateWhereClause() + SPACE + (ExtendedSearchController.useFull() ? generateOrderByClause() : generateOrderByClauseShort()) + SPACE + "AS " + SmallContentImpl.class.getName(); 331 } 332 333 336 private String generateSelectClauseShort() 337 { 338 return SELECT_KEYWORD + SPACE + 339 CONTENT_ALIAS + ".ContId" + 340 COMMA + CONTENT_ALIAS + ".name" + 341 COMMA + CONTENT_ALIAS + ".publishDateTime" + 342 COMMA + CONTENT_ALIAS + ".expireDateTime" + 343 COMMA + CONTENT_ALIAS + ".isBranch" + 344 COMMA + CONTENT_ALIAS + ".isProtected" + 345 COMMA + CONTENT_ALIAS + ".creator" + 346 COMMA + CONTENT_ALIAS + ".contentTypeDefId" + 347 COMMA + CONTENT_ALIAS + ".repositoryId" + 348 COMMA + CONTENT_ALIAS + ".parentContId" + 349 COMMA + CONTENT_ALIAS + ".ContId"; 350 } 351 352 355 private String generateSelectClause() 356 { 357 return SELECT_KEYWORD + SPACE + 358 CONTENT_ALIAS + ".contentId" + 359 COMMA + CONTENT_ALIAS + ".name" + 360 COMMA + CONTENT_ALIAS + ".publishDateTime" + 361 COMMA + CONTENT_ALIAS + ".expireDateTime" + 362 COMMA + CONTENT_ALIAS + ".isBranch" + 363 COMMA + CONTENT_ALIAS + ".isProtected" + 364 COMMA + CONTENT_ALIAS + ".creator" + 365 COMMA + CONTENT_ALIAS + ".contentTypeDefinitionId" + 366 COMMA + CONTENT_ALIAS + ".repositoryId" + 367 COMMA + CONTENT_ALIAS + ".parentContentId" + 368 COMMA + CONTENT_ALIAS + ".contentId"; 369 } 370 371 374 private String generateFromClause() 375 { 376 final List tables = new ArrayList (); 377 tables.add(getCONTENT_TABLE() + SPACE + CONTENT_ALIAS); 378 tables.add(getCONTENT_VERSION_TABLE() + SPACE + CONTENT_VERSION_ALIAS); 379 tables.addAll(getCategoryTables()); 380 381 return FROM_KEYWORD + SPACE + joinCollection(tables, COMMA); 382 } 383 384 387 private String generateWhereClause() 388 { 389 final List clauses = new ArrayList (); 390 clauses.addAll(getContentWhereClauses()); 391 clauses.add(getContentVersionWhereClauses()); 392 if(criterias.hasFreetextCritera()) 393 { 394 clauses.add(getFreetextWhereClause()); 395 } 396 clauses.addAll(getCategoriesWhereClauses()); 397 clauses.addAll(getDateWhereClauses()); 398 return WHERE_KEYWORD + SPACE + joinCollection(clauses, SPACE + AND + SPACE); 399 } 400 401 404 private List getContentWhereClauses() 405 { 406 final List clauses = new ArrayList (); 407 408 clauses.add(CV_ACTIVE_CLAUSE); 409 clauses.add(MessageFormat.format(getCV_LATEST_VERSION_CLAUSE(), new Object [] { criterias.getLanguage().getId().toString(), CmsPropertyHandler.getOperatingMode() })); 410 clauses.add(getCV_CONTENT_JOIN()); 411 clauses.add(MessageFormat.format(CV_STATE_CLAUSE, new Object [] { getBindingVariable() })); 412 bindings.add(criterias.getStateId()); 413 414 if(criterias.hasLanguageCriteria()) 415 { 416 logger.debug(" CRITERA[language]"); 417 clauses.add(MessageFormat.format(CV_LANGUAGE_CLAUSE, new Object [] { getBindingVariable() })); 418 bindings.add(criterias.getLanguage().getId()); 419 } 420 421 return clauses; 422 } 423 424 427 private String generateOrderByClauseShort() 428 { 429 return "ORDER BY " + CONTENT_ALIAS + ".ContId"; 430 } 431 432 435 private String generateOrderByClause() 436 { 437 return "ORDER BY " + CONTENT_ALIAS + ".contentId"; 438 } 439 440 441 444 private String getContentVersionWhereClauses() 445 { 446 final List expressions = new ArrayList (); 447 if(criterias.hasContentTypeDefinitionVOsCriteria()) 448 { 449 logger.debug(" CRITERA[content type definition]"); 450 for(final Iterator i=criterias.getContentTypeDefinitions().iterator(); i.hasNext(); ) 451 { 452 final ContentTypeDefinitionVO contentTypeDefinitionVO = (ContentTypeDefinitionVO) i.next(); 453 expressions.add(MessageFormat.format(getC_CONTENT_TYPE_CLAUSE(), new Object [] { getBindingVariable() })); 454 bindings.add(contentTypeDefinitionVO.getId()); 455 } 456 } 457 return "(" + joinCollection(expressions, SPACE + OR + SPACE) + ")"; 458 } 459 460 463 private List getCategoriesWhereClauses() 464 { 465 final List clauses = new ArrayList (); 466 if(criterias.hasCategoryConditions()) 467 { 468 logger.debug(" CRITERA[categories]"); 469 clauses.add(criterias.getCategories().getWhereClauseOQL(bindings)); 470 } 471 return clauses; 472 } 473 474 477 private List getDateWhereClauses() 478 { 479 final List clauses = new ArrayList (); 480 switch(criterias.getDateCriteriaType()) 481 { 482 case ExtendedSearchCriterias.FROM_DATE_CRITERIA_TYPE: 483 logger.debug(" CRITERA[date : from]"); 484 clauses.add(MessageFormat.format(FROM_DATE_CLAUSE, new Object [] { getBindingVariable() })); 485 bindings.add(criterias.getFromDate()); 486 break; 487 case ExtendedSearchCriterias.TO_DATE_CRITERIA_TYPE: 488 logger.debug(" CRITERA[date : to]"); 489 clauses.add(MessageFormat.format(TO_DATE_CLAUSE, new Object [] { getBindingVariable() })); 490 bindings.add(criterias.getToDate()); 491 break; 492 case ExtendedSearchCriterias.BOTH_DATE_CRITERIA_TYPE: 493 logger.debug(" CRITERA[date : between]"); 494 clauses.add(MessageFormat.format(FROM_DATE_CLAUSE, new Object [] { getBindingVariable() })); 495 bindings.add(criterias.getFromDate()); 496 clauses.add(MessageFormat.format(TO_DATE_CLAUSE, new Object [] { getBindingVariable() })); 497 bindings.add(criterias.getToDate()); 498 break; 499 } 500 return clauses; 501 } 502 503 506 private String getFreetextWhereClause() 507 { 508 logger.debug(" CRITERA[freetext]"); 509 final List expressions = new ArrayList (); 510 if(criterias.hasFreetextCritera()) 511 { 512 for(final Iterator i=criterias.getXmlAttributes().iterator(); i.hasNext(); ) 513 { 514 final String xmlAttribute = (String ) i.next(); 515 final String freeTextExpression = MessageFormat.format(getFREETEXT_EXPRESSION(), new Object [] { getBindingVariable() }); 516 final String freeTextVariable = MessageFormat.format(FREETEXT_EXPRESSION_VARIABLE, new Object [] { xmlAttribute, criterias.getFreetext() }); 517 518 bindings.add(freeTextVariable); 519 expressions.add(freeTextExpression); 520 } 521 } 522 return "(" + joinCollection(expressions, SPACE + OR + SPACE) + ")"; 523 } 524 525 528 private List getCategoryTables() 529 { 530 final List tables = new ArrayList (); 531 if(criterias.hasCategoryConditions()) 532 { 533 tables.addAll(criterias.getCategories().getFromClauseTables()); 534 } 535 return tables; 536 } 537 538 541 private String joinCollection(final Collection collection, final String delimiter) 542 { 543 final StringBuffer sb = new StringBuffer (); 544 for(Iterator i=collection.iterator(); i.hasNext(); ) 545 { 546 String element = (String ) i.next(); 547 sb.append(element + (i.hasNext() ? delimiter : "")); 548 } 549 return sb.toString(); 550 } 551 552 555 private String getBindingVariable() 556 { 557 return "$" + (bindings.size() + 1); 558 } 559 560 public static String getCONTENT_TABLE() 561 { 562 return (ExtendedSearchController.useFull()) ? CONTENT_TABLE : CONTENT_TABLE_SHORT; 563 } 564 public static String getCONTENT_VERSION_TABLE() 565 { 566 return (ExtendedSearchController.useFull()) ? CONTENT_VERSION_TABLE : CONTENT_VERSION_TABLE_SHORT; 567 } 568 public static String getC_CONTENT_TYPE_CLAUSE() 569 { 570 return (ExtendedSearchController.useFull()) ? C_CONTENT_TYPE_CLAUSE : C_CONTENT_TYPE_CLAUSE_SHORT; 571 } 572 public static String getCV_CONTENT_JOIN() 573 { 574 return (ExtendedSearchController.useFull()) ? CV_CONTENT_JOIN : CV_CONTENT_JOIN_SHORT; 575 } 576 public static String getCV_LATEST_VERSION_CLAUSE() 577 { 578 return (ExtendedSearchController.useFull()) ? CV_LATEST_VERSION_CLAUSE : CV_LATEST_VERSION_CLAUSE_SHORT; 579 } 580 public static String getFREETEXT_EXPRESSION() 581 { 582 return (ExtendedSearchController.useFull()) ? FREETEXT_EXPRESSION : FREETEXT_EXPRESSION_SHORT; 583 } 584 } 585 | Popular Tags |