001/* 002 * This library is part of OpenCms - 003 * the Open Source Content Management System 004 * 005 * Copyright (c) Alkacon Software GmbH & Co. KG (https://www.alkacon.com) 006 * 007 * This library is free software; you can redistribute it and/or 008 * modify it under the terms of the GNU Lesser General Public 009 * License as published by the Free Software Foundation; either 010 * version 2.1 of the License, or (at your option) any later version. 011 * 012 * This library is distributed in the hope that it will be useful, 013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 015 * Lesser General Public License for more details. 016 * 017 * For further information about Alkacon Software GmbH & Co. KG, please see the 018 * company website: https://www.alkacon.com 019 * 020 * For further information about OpenCms, please see the 021 * project website: https://www.opencms.org 022 * 023 * You should have received a copy of the GNU Lesser General Public 024 * License along with this library; if not, write to the Free Software 025 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 026 */ 027 028package org.opencms.db.generic; 029 030import org.opencms.configuration.CmsConfigurationManager; 031import org.opencms.configuration.CmsParameterConfiguration; 032import org.opencms.db.CmsAliasFilter; 033import org.opencms.db.CmsDbContext; 034import org.opencms.db.CmsDbEntryNotFoundException; 035import org.opencms.db.CmsDbIoException; 036import org.opencms.db.CmsDbSqlException; 037import org.opencms.db.CmsDriverManager; 038import org.opencms.db.CmsModificationContext; 039import org.opencms.db.CmsPreparedStatementIntParameter; 040import org.opencms.db.CmsPreparedStatementLongParameter; 041import org.opencms.db.CmsPreparedStatementStringParameter; 042import org.opencms.db.CmsPublishList; 043import org.opencms.db.CmsPublishedResource; 044import org.opencms.db.CmsResourceState; 045import org.opencms.db.CmsVisitEntryFilter; 046import org.opencms.db.I_CmsDriver; 047import org.opencms.db.I_CmsHistoryDriver; 048import org.opencms.db.I_CmsPreparedStatementParameter; 049import org.opencms.db.I_CmsProjectDriver; 050import org.opencms.db.I_CmsVfsDriver; 051import org.opencms.db.log.CmsLogEntry; 052import org.opencms.db.log.CmsLogEntryType; 053import org.opencms.db.log.CmsLogFilter; 054import org.opencms.db.userpublishlist.CmsUserPublishListEntry; 055import org.opencms.file.CmsDataAccessException; 056import org.opencms.file.CmsFile; 057import org.opencms.file.CmsFolder; 058import org.opencms.file.CmsGroup; 059import org.opencms.file.CmsProject; 060import org.opencms.file.CmsProperty; 061import org.opencms.file.CmsPropertyDefinition; 062import org.opencms.file.CmsResource; 063import org.opencms.file.CmsResourceFilter; 064import org.opencms.file.CmsUser; 065import org.opencms.file.CmsVfsResourceAlreadyExistsException; 066import org.opencms.file.CmsVfsResourceNotFoundException; 067import org.opencms.file.history.CmsHistoryFile; 068import org.opencms.file.types.CmsResourceTypeFolder; 069import org.opencms.i18n.CmsMessageContainer; 070import org.opencms.lock.CmsLock; 071import org.opencms.lock.CmsLockType; 072import org.opencms.main.CmsEvent; 073import org.opencms.main.CmsException; 074import org.opencms.main.CmsLog; 075import org.opencms.main.I_CmsEventListener; 076import org.opencms.main.OpenCms; 077import org.opencms.publish.CmsPublishJobInfoBean; 078import org.opencms.relations.CmsRelationFilter; 079import org.opencms.report.I_CmsReport; 080import org.opencms.security.CmsOrganizationalUnit; 081import org.opencms.security.I_CmsPrincipal; 082import org.opencms.staticexport.CmsStaticExportManager; 083import org.opencms.util.CmsPair; 084import org.opencms.util.CmsStringUtil; 085import org.opencms.util.CmsUUID; 086 087import java.io.ByteArrayInputStream; 088import java.io.ByteArrayOutputStream; 089import java.io.IOException; 090import java.io.ObjectInputStream; 091import java.io.ObjectOutputStream; 092import java.sql.Connection; 093import java.sql.PreparedStatement; 094import java.sql.ResultSet; 095import java.sql.SQLException; 096import java.util.ArrayList; 097import java.util.Collection; 098import java.util.Collections; 099import java.util.HashMap; 100import java.util.HashSet; 101import java.util.Iterator; 102import java.util.List; 103import java.util.Map; 104import java.util.Set; 105 106import org.apache.commons.logging.Log; 107 108import com.google.common.collect.Sets; 109 110/** 111 * Generic (ANSI-SQL) implementation of the project driver methods.<p> 112 * 113 * @since 6.0.0 114 */ 115public class CmsProjectDriver implements I_CmsDriver, I_CmsProjectDriver { 116 117 /** 118 * This private class is a temporary storage for the method {@link CmsProjectDriver#readLocks(CmsDbContext)}.<p> 119 */ 120 private class CmsTempResourceLock { 121 122 /** The lock type. */ 123 private int m_lockType; 124 125 /** The project id. */ 126 private CmsUUID m_projectId; 127 128 /** The resource path. */ 129 private String m_resourcePath; 130 131 /** The user id. */ 132 private CmsUUID m_userId; 133 134 /** 135 * The constructor.<p> 136 * 137 * @param resourcePath resource path 138 * @param userId user id 139 * @param projectId project id 140 * @param lockType lock type 141 */ 142 public CmsTempResourceLock(String resourcePath, CmsUUID userId, CmsUUID projectId, int lockType) { 143 144 m_resourcePath = resourcePath; 145 m_userId = userId; 146 m_projectId = projectId; 147 m_lockType = lockType; 148 } 149 150 /** 151 * Returns the lockType.<p> 152 * 153 * @return the lockType 154 */ 155 public int getLockType() { 156 157 return m_lockType; 158 } 159 160 /** 161 * Returns the projectId.<p> 162 * 163 * @return the projectId 164 */ 165 public CmsUUID getProjectId() { 166 167 return m_projectId; 168 } 169 170 /** 171 * Returns the resourcePath.<p> 172 * 173 * @return the resourcePath 174 */ 175 public String getResourcePath() { 176 177 return m_resourcePath; 178 } 179 180 /** 181 * Returns the userId.<p> 182 * 183 * @return the userId 184 */ 185 public CmsUUID getUserId() { 186 187 return m_userId; 188 } 189 190 } 191 192 /** Attribute name for reading the project of a resource. */ 193 public static final String DBC_ATTR_READ_PROJECT_FOR_RESOURCE = "DBC_ATTR_READ_PROJECT_FOR_RESOURCE"; 194 195 /** The log object for this class. */ 196 private static final Log LOG = CmsLog.getLog(org.opencms.db.generic.CmsProjectDriver.class); 197 198 /** The driver manager. */ 199 protected CmsDriverManager m_driverManager; 200 201 /** The SQL manager. */ 202 protected CmsSqlManager m_sqlManager; 203 204 /** 205 * @see org.opencms.db.I_CmsProjectDriver#cleanupPublishHistory(org.opencms.db.CmsDbContext, org.opencms.db.generic.CmsPublishHistoryCleanupFilter) 206 */ 207 public int cleanupPublishHistory(CmsDbContext dbc, CmsPublishHistoryCleanupFilter filter) 208 throws CmsDataAccessException { 209 210 Connection conn = null; 211 PreparedStatement stmt = null; 212 int rowsAffected = 0; 213 214 try { 215 // get a JDBC connection from the OpenCms standard pool 216 conn = m_sqlManager.getConnection(dbc); 217 switch (filter.getMode()) { 218 219 case single: 220 default: 221 stmt = m_sqlManager.getPreparedStatement(conn, "C_CLEANUP_PUBLISH_HISTORY_SINGLE"); 222 stmt.setString(1, filter.getHistoryId().toString()); 223 rowsAffected = stmt.executeUpdate(); 224 break; 225 case allUnreferenced: 226 String statementText = m_sqlManager.readQuery("C_CLEANUP_PUBLISH_HISTORY_ALL"); 227 if (filter.getExceptions().size() > 0) { 228 List<String> parts = new ArrayList<>(); 229 // it's safe to construct the clause as a string here because UUIDs can only contain dashes and hex digits 230 parts.add("'" + CmsUUID.getNullUUID() + "'"); 231 for (CmsUUID id : filter.getExceptions()) { 232 parts.add("'" + id.toString() + "'"); 233 } 234 String exceptionListStr = "(" + CmsStringUtil.listAsString(parts, ",") + ")"; 235 statementText += " AND CMS_PUBLISH_HISTORY.HISTORY_ID NOT IN " + exceptionListStr; 236 } 237 stmt = m_sqlManager.getPreparedStatementForSql(conn, statementText); 238 rowsAffected = stmt.executeUpdate(); 239 break; 240 } 241 LOG.info( 242 "executed publish list cleanup in mode " + filter.getMode() + ", " + rowsAffected + " rows deleted"); 243 return rowsAffected; 244 } catch (SQLException e) { 245 throw new CmsDbSqlException( 246 Messages.get().container(Messages.ERR_GENERIC_SQL_1, CmsDbSqlException.getErrorQuery(stmt)), 247 e); 248 } finally { 249 m_sqlManager.closeAll(dbc, conn, stmt, null); 250 251 } 252 253 } 254 255 /** 256 * @see org.opencms.db.I_CmsProjectDriver#createProject(org.opencms.db.CmsDbContext, CmsUUID, org.opencms.file.CmsUser, org.opencms.file.CmsGroup, org.opencms.file.CmsGroup, java.lang.String, java.lang.String, int, CmsProject.CmsProjectType) 257 */ 258 public CmsProject createProject( 259 CmsDbContext dbc, 260 CmsUUID id, 261 CmsUser owner, 262 CmsGroup group, 263 CmsGroup managergroup, 264 String projectFqn, 265 String description, 266 int flags, 267 CmsProject.CmsProjectType type) 268 throws CmsDataAccessException { 269 270 CmsProject project = null; 271 272 if ((description == null) || (description.length() < 1)) { 273 description = " "; 274 } 275 276 Connection conn = null; 277 PreparedStatement stmt = null; 278 279 try { 280 // get a JDBC connection from the OpenCms standard pool 281 conn = m_sqlManager.getConnection(dbc); 282 stmt = m_sqlManager.getPreparedStatement(conn, "C_PROJECTS_CREATE_10"); 283 284 stmt.setString(1, id.toString()); 285 stmt.setString(2, owner.getId().toString()); 286 stmt.setString(3, group.getId().toString()); 287 stmt.setString(4, managergroup.getId().toString()); 288 stmt.setString(5, CmsOrganizationalUnit.getSimpleName(projectFqn)); 289 stmt.setString(6, description); 290 stmt.setInt(7, flags); 291 stmt.setInt(9, type.getMode()); 292 stmt.setString(10, CmsOrganizationalUnit.SEPARATOR + CmsOrganizationalUnit.getParentFqn(projectFqn)); 293 294 synchronized (this) { 295 long createTime = System.currentTimeMillis(); 296 stmt.setLong(8, createTime); 297 stmt.executeUpdate(); 298 try { 299 // this is an ugly hack, but for MySQL (and maybe other DBs as well) 300 // there is a UNIQUE INDEX constraint on the project name+createTime 301 // so theoretically if 2 projects with the same name are created very fast, this 302 // SQL restraint would be violated if we don't wait here 303 Thread.sleep(50); 304 } catch (InterruptedException e) { 305 // continue 306 } 307 project = new CmsProject( 308 id, 309 projectFqn, 310 description, 311 owner.getId(), 312 group.getId(), 313 managergroup.getId(), 314 flags, 315 createTime, 316 type); 317 } 318 } catch (SQLException e) { 319 throw new CmsDbSqlException( 320 Messages.get().container(Messages.ERR_GENERIC_SQL_1, CmsDbSqlException.getErrorQuery(stmt)), 321 e); 322 } finally { 323 m_sqlManager.closeAll(dbc, conn, stmt, null); 324 } 325 326 return project; 327 } 328 329 /** 330 * @see org.opencms.db.I_CmsProjectDriver#createProjectResource(org.opencms.db.CmsDbContext, CmsUUID, java.lang.String) 331 */ 332 public void createProjectResource(CmsDbContext dbc, CmsUUID projectId, String resourcePath) 333 throws CmsDataAccessException { 334 335 // do not create entries for online-project 336 PreparedStatement stmt = null; 337 Connection conn = null; 338 339 boolean projectResourceExists = false; 340 try { 341 readProjectResource(dbc, projectId, resourcePath); 342 projectResourceExists = true; 343 } catch (CmsVfsResourceNotFoundException e) { 344 // resource does not exist yet, everything is okay 345 projectResourceExists = false; 346 } 347 348 if (projectResourceExists) { 349 throw new CmsVfsResourceAlreadyExistsException( 350 Messages.get().container( 351 Messages.ERR_RESOURCE_WITH_NAME_ALREADY_EXISTS_1, 352 dbc.removeSiteRoot(resourcePath))); 353 } 354 355 try { 356 conn = getSqlManager().getConnection(dbc); 357 stmt = m_sqlManager.getPreparedStatement(conn, "C_PROJECTRESOURCES_CREATE_2"); 358 359 // write new resource to the database 360 stmt.setString(1, projectId.toString()); 361 stmt.setString(2, resourcePath); 362 363 stmt.executeUpdate(); 364 } catch (SQLException e) { 365 throw new CmsDbSqlException( 366 Messages.get().container(Messages.ERR_GENERIC_SQL_1, CmsDbSqlException.getErrorQuery(stmt)), 367 e); 368 } finally { 369 m_sqlManager.closeAll(dbc, conn, stmt, null); 370 } 371 } 372 373 /** 374 * @see org.opencms.db.I_CmsProjectDriver#createPublishJob(org.opencms.db.CmsDbContext, org.opencms.publish.CmsPublishJobInfoBean) 375 */ 376 public void createPublishJob(CmsDbContext dbc, CmsPublishJobInfoBean publishJob) throws CmsDataAccessException { 377 378 Connection conn = null; 379 PreparedStatement stmt = null; 380 381 try { 382 CmsPublishJobInfoBean currentJob = readPublishJob(dbc, publishJob.getPublishHistoryId()); 383 LOG.error("wanted to write: " + publishJob); 384 LOG.error("already on db: " + currentJob); 385 return; 386 } catch (CmsDbEntryNotFoundException e) { 387 // ok, this is the expected behavior 388 } 389 try { 390 conn = m_sqlManager.getConnection(dbc); 391 stmt = m_sqlManager.getPreparedStatement(conn, "C_PUBLISHJOB_CREATE"); 392 393 stmt.setString(1, publishJob.getPublishHistoryId().toString()); 394 stmt.setString(2, publishJob.getProjectId().toString()); 395 stmt.setString(3, publishJob.getProjectName()); 396 stmt.setString(4, publishJob.getUserId().toString()); 397 stmt.setString(5, publishJob.getLocale().toString()); 398 stmt.setInt(6, publishJob.getFlags()); 399 stmt.setInt(7, publishJob.getSize()); 400 stmt.setLong(8, publishJob.getEnqueueTime()); 401 stmt.setLong(9, publishJob.getStartTime()); 402 stmt.setLong(10, publishJob.getFinishTime()); 403 404 byte[] publishList = internalSerializePublishList(publishJob.getPublishList()); 405 if (publishList.length < 2000) { 406 stmt.setBytes(11, publishList); 407 } else { 408 stmt.setBinaryStream(11, new ByteArrayInputStream(publishList), publishList.length); 409 } 410 411 stmt.executeUpdate(); 412 } catch (SQLException e) { 413 throw new CmsDbSqlException( 414 Messages.get().container(Messages.ERR_GENERIC_SQL_1, CmsDbSqlException.getErrorQuery(stmt)), 415 e); 416 } catch (IOException e) { 417 throw new CmsDbIoException( 418 Messages.get().container( 419 Messages.ERR_SERIALIZING_PUBLISHLIST_1, 420 publishJob.getPublishHistoryId().toString()), 421 e); 422 } finally { 423 m_sqlManager.closeAll(dbc, conn, stmt, null); 424 } 425 } 426 427 /** 428 * @see org.opencms.db.I_CmsProjectDriver#deleteAllStaticExportPublishedResources(org.opencms.db.CmsDbContext, int) 429 */ 430 public void deleteAllStaticExportPublishedResources(CmsDbContext dbc, int linkType) throws CmsDataAccessException { 431 432 Connection conn = null; 433 PreparedStatement stmt = null; 434 435 try { 436 conn = m_sqlManager.getConnection(dbc); 437 stmt = m_sqlManager.getPreparedStatement(conn, "C_STATICEXPORT_DELETE_ALL_PUBLISHED_LINKS"); 438 stmt.setInt(1, linkType); 439 stmt.executeUpdate(); 440 } catch (SQLException e) { 441 throw new CmsDbSqlException( 442 Messages.get().container(Messages.ERR_GENERIC_SQL_1, CmsDbSqlException.getErrorQuery(stmt)), 443 e); 444 } finally { 445 m_sqlManager.closeAll(dbc, conn, stmt, null); 446 } 447 } 448 449 /** 450 * @see org.opencms.db.I_CmsProjectDriver#deleteLog(org.opencms.db.CmsDbContext, org.opencms.db.log.CmsLogFilter) 451 */ 452 public void deleteLog(CmsDbContext dbc, CmsLogFilter filter) throws CmsDataAccessException { 453 454 Connection conn = null; 455 PreparedStatement stmt = null; 456 457 try { 458 conn = m_sqlManager.getConnection(dbc); 459 // compose statement 460 StringBuffer queryBuf = new StringBuffer(256); 461 queryBuf.append(m_sqlManager.readQuery("C_LOG_DELETE_ENTRIES")); 462 463 CmsPair<String, List<I_CmsPreparedStatementParameter>> conditionsAndParams = prepareLogConditions(filter); 464 queryBuf.append(conditionsAndParams.getFirst()); 465 if (LOG.isDebugEnabled()) { 466 LOG.debug(queryBuf.toString()); 467 } 468 stmt = m_sqlManager.getPreparedStatementForSql(conn, queryBuf.toString()); 469 List<I_CmsPreparedStatementParameter> params = conditionsAndParams.getSecond(); 470 for (int i = 0; i < params.size(); i++) { 471 I_CmsPreparedStatementParameter param = conditionsAndParams.getSecond().get(i); 472 param.insertIntoStatement(stmt, i + 1); 473 } 474 475 // execute 476 stmt.executeUpdate(); 477 } catch (SQLException e) { 478 throw new CmsDbSqlException( 479 Messages.get().container(Messages.ERR_GENERIC_SQL_1, CmsDbSqlException.getErrorQuery(stmt)), 480 e); 481 } finally { 482 m_sqlManager.closeAll(dbc, conn, stmt, null); 483 } 484 } 485 486 /** 487 * @see org.opencms.db.I_CmsProjectDriver#deleteProject(org.opencms.db.CmsDbContext, org.opencms.file.CmsProject) 488 */ 489 public void deleteProject(CmsDbContext dbc, CmsProject project) throws CmsDataAccessException { 490 491 // delete the resources from project_resources 492 deleteProjectResources(dbc, project); 493 494 // remove the project id form all resources within their project 495 unmarkProjectResources(dbc, project); 496 497 // finally delete the project 498 Connection conn = null; 499 PreparedStatement stmt = null; 500 try { 501 conn = m_sqlManager.getConnection(dbc); 502 stmt = m_sqlManager.getPreparedStatement(conn, "C_PROJECTS_DELETE_1"); 503 // create the statement 504 stmt.setString(1, project.getUuid().toString()); 505 stmt.executeUpdate(); 506 } catch (SQLException e) { 507 throw new CmsDbSqlException( 508 Messages.get().container(Messages.ERR_GENERIC_SQL_1, CmsDbSqlException.getErrorQuery(stmt)), 509 e); 510 } finally { 511 m_sqlManager.closeAll(dbc, conn, stmt, null); 512 } 513 } 514 515 /** 516 * @see org.opencms.db.I_CmsProjectDriver#deleteProjectResource(org.opencms.db.CmsDbContext, CmsUUID, java.lang.String) 517 */ 518 public void deleteProjectResource(CmsDbContext dbc, CmsUUID projectId, String resourceName) 519 throws CmsDataAccessException { 520 521 Connection conn = null; 522 PreparedStatement stmt = null; 523 try { 524 conn = m_sqlManager.getConnection(dbc); 525 stmt = m_sqlManager.getPreparedStatement(conn, "C_PROJECTRESOURCES_DELETE_2"); 526 // delete resource from the database 527 stmt.setString(1, projectId.toString()); 528 stmt.setString(2, resourceName); 529 stmt.executeUpdate(); 530 } catch (SQLException e) { 531 throw new CmsDbSqlException( 532 Messages.get().container(Messages.ERR_GENERIC_SQL_1, CmsDbSqlException.getErrorQuery(stmt)), 533 e); 534 } finally { 535 m_sqlManager.closeAll(dbc, conn, stmt, null); 536 } 537 } 538 539 /** 540 * @see org.opencms.db.I_CmsProjectDriver#deleteProjectResources(org.opencms.db.CmsDbContext, org.opencms.file.CmsProject) 541 */ 542 public void deleteProjectResources(CmsDbContext dbc, CmsProject project) throws CmsDataAccessException { 543 544 Connection conn = null; 545 PreparedStatement stmt = null; 546 547 try { 548 conn = m_sqlManager.getConnection(dbc); 549 stmt = m_sqlManager.getPreparedStatement(conn, "C_PROJECTRESOURCES_DELETEALL_1"); 550 stmt.setString(1, project.getUuid().toString()); 551 stmt.executeUpdate(); 552 } catch (SQLException e) { 553 throw new CmsDbSqlException( 554 Messages.get().container(Messages.ERR_GENERIC_SQL_1, CmsDbSqlException.getErrorQuery(stmt)), 555 e); 556 } finally { 557 m_sqlManager.closeAll(dbc, conn, stmt, null); 558 } 559 } 560 561 /** 562 * @see org.opencms.db.I_CmsProjectDriver#deletePublishHistory(org.opencms.db.CmsDbContext, CmsUUID, int) 563 */ 564 public void deletePublishHistory(CmsDbContext dbc, CmsUUID projectId, int maxpublishTag) 565 throws CmsDataAccessException { 566 567 PreparedStatement stmt = null; 568 Connection conn = null; 569 570 try { 571 conn = m_sqlManager.getConnection(dbc); 572 stmt = m_sqlManager.getPreparedStatement(conn, projectId, "C_DELETE_PUBLISH_HISTORY"); 573 stmt.setInt(1, maxpublishTag); 574 stmt.executeUpdate(); 575 } catch (SQLException e) { 576 throw new CmsDbSqlException( 577 Messages.get().container(Messages.ERR_GENERIC_SQL_1, CmsDbSqlException.getErrorQuery(stmt)), 578 e); 579 } finally { 580 m_sqlManager.closeAll(dbc, conn, stmt, null); 581 } 582 } 583 584 /** 585 * @see org.opencms.db.I_CmsProjectDriver#deletePublishHistoryEntry(org.opencms.db.CmsDbContext, org.opencms.util.CmsUUID, org.opencms.db.CmsPublishedResource) 586 */ 587 public void deletePublishHistoryEntry( 588 CmsDbContext dbc, 589 CmsUUID publishHistoryId, 590 CmsPublishedResource publishedResource) 591 throws CmsDataAccessException { 592 593 Connection conn = null; 594 PreparedStatement stmt = null; 595 596 try { 597 conn = m_sqlManager.getConnection(dbc); 598 stmt = m_sqlManager.getPreparedStatement(conn, "C_RESOURCES_DELETE_PUBLISH_HISTORY_ENTRY"); 599 stmt.setString(1, publishHistoryId.toString()); 600 stmt.setInt(2, publishedResource.getPublishTag()); 601 stmt.setString(3, publishedResource.getStructureId().toString()); 602 stmt.setString(4, publishedResource.getRootPath()); 603 stmt.executeUpdate(); 604 } catch (SQLException e) { 605 throw new CmsDbSqlException( 606 Messages.get().container(Messages.ERR_GENERIC_SQL_1, CmsDbSqlException.getErrorQuery(stmt)), 607 e); 608 } finally { 609 m_sqlManager.closeAll(dbc, conn, stmt, null); 610 } 611 } 612 613 /** 614 * @see org.opencms.db.I_CmsProjectDriver#deletePublishJob(org.opencms.db.CmsDbContext, org.opencms.util.CmsUUID) 615 */ 616 public void deletePublishJob(CmsDbContext dbc, CmsUUID publishHistoryId) throws CmsDataAccessException { 617 618 Connection conn = null; 619 PreparedStatement stmt = null; 620 621 try { 622 conn = m_sqlManager.getConnection(dbc); 623 stmt = m_sqlManager.getPreparedStatement(conn, "C_PUBLISHJOB_DELETE"); 624 stmt.setString(1, publishHistoryId.toString()); 625 stmt.executeUpdate(); 626 } catch (SQLException e) { 627 throw new CmsDbSqlException( 628 Messages.get().container(Messages.ERR_GENERIC_SQL_1, CmsDbSqlException.getErrorQuery(stmt)), 629 e); 630 } finally { 631 m_sqlManager.closeAll(dbc, conn, stmt, null); 632 } 633 } 634 635 /** 636 * @see org.opencms.db.I_CmsProjectDriver#deletePublishList(org.opencms.db.CmsDbContext, org.opencms.util.CmsUUID) 637 */ 638 public void deletePublishList(CmsDbContext dbc, CmsUUID publishHistoryId) throws CmsDataAccessException { 639 640 Connection conn = null; 641 PreparedStatement stmt = null; 642 643 try { 644 conn = m_sqlManager.getConnection(dbc); 645 stmt = m_sqlManager.getPreparedStatement(conn, "C_PUBLISHJOB_DELETE_PUBLISHLIST"); 646 stmt.setString(1, publishHistoryId.toString()); 647 stmt.executeUpdate(); 648 } catch (SQLException e) { 649 throw new CmsDbSqlException( 650 Messages.get().container(Messages.ERR_GENERIC_SQL_1, CmsDbSqlException.getErrorQuery(stmt)), 651 e); 652 } finally { 653 m_sqlManager.closeAll(dbc, conn, stmt, null); 654 } 655 } 656 657 /** 658 * @see org.opencms.db.I_CmsProjectDriver#deleteStaticExportPublishedResource(org.opencms.db.CmsDbContext, java.lang.String, int, java.lang.String) 659 */ 660 public void deleteStaticExportPublishedResource( 661 CmsDbContext dbc, 662 String resourceName, 663 int linkType, 664 String linkParameter) 665 throws CmsDataAccessException { 666 667 Connection conn = null; 668 PreparedStatement stmt = null; 669 670 try { 671 conn = m_sqlManager.getConnection(dbc); 672 if (linkParameter == null) { 673 stmt = m_sqlManager.getPreparedStatement(conn, "C_STATICEXPORT_DELETE_RFSPATH_PUBLISHED_LINKS"); 674 stmt.setString(1, resourceName); 675 stmt.setInt(2, linkType); 676 stmt.executeUpdate(); 677 } else { 678 stmt = m_sqlManager.getPreparedStatement(conn, "C_STATICEXPORT_DELETE_PUBLISHED_LINKS"); 679 stmt.setString(1, resourceName); 680 stmt.setInt(2, linkType); 681 stmt.setString(3, linkParameter); 682 stmt.executeUpdate(); 683 } 684 } catch (SQLException e) { 685 throw new CmsDbSqlException( 686 Messages.get().container(Messages.ERR_GENERIC_SQL_1, CmsDbSqlException.getErrorQuery(stmt)), 687 e); 688 } finally { 689 m_sqlManager.closeAll(dbc, conn, stmt, null); 690 } 691 } 692 693 /** 694 * @see org.opencms.db.I_CmsProjectDriver#deleteUserPublishListEntries(org.opencms.db.CmsDbContext, java.util.List) 695 */ 696 public void deleteUserPublishListEntries(CmsDbContext dbc, List<CmsUserPublishListEntry> publishListDeletions) 697 throws CmsDbSqlException { 698 699 if (publishListDeletions.isEmpty()) { 700 return; 701 } 702 Connection conn = null; 703 PreparedStatement stmt = null; 704 705 try { 706 conn = m_sqlManager.getConnection(dbc); 707 String sql = m_sqlManager.readQuery("C_USER_PUBLISH_LIST_DELETE_3"); 708 stmt = m_sqlManager.getPreparedStatementForSql(conn, sql); 709 for (CmsUserPublishListEntry entry : publishListDeletions) { 710 stmt.setString(1, entry.getStructureId().toString()); 711 stmt.setString(2, entry.getUserId() != null ? entry.getUserId().toString() : null); 712 stmt.setInt(3, entry.getUserId() == null ? 1 : 0); 713 stmt.addBatch(); 714 } 715 stmt.executeBatch(); 716 } catch (SQLException e) { 717 throw new CmsDbSqlException( 718 Messages.get().container(Messages.ERR_GENERIC_SQL_1, CmsDbSqlException.getErrorQuery(stmt)), 719 e); 720 } finally { 721 m_sqlManager.closeAll(dbc, conn, stmt, null); 722 } 723 724 } 725 726 /** 727 * @see org.opencms.db.I_CmsProjectDriver#destroy() 728 */ 729 public void destroy() throws Throwable { 730 731 m_sqlManager = null; 732 m_driverManager = null; 733 734 if (CmsLog.INIT.isInfoEnabled()) { 735 CmsLog.INIT.info(Messages.get().getBundle().key(Messages.INIT_SHUTDOWN_DRIVER_1, getClass().getName())); 736 } 737 } 738 739 /** 740 * @see org.opencms.db.I_CmsProjectDriver#fillDefaults(org.opencms.db.CmsDbContext) 741 */ 742 public void fillDefaults(CmsDbContext dbc) throws CmsDataAccessException { 743 744 try { 745 if (readProject(dbc, CmsProject.ONLINE_PROJECT_ID) != null) { 746 // online-project exists - no need of filling defaults 747 return; 748 } 749 } catch (CmsDataAccessException exc) { 750 // ignore the exception - the project was not readable so fill in the defaults 751 } 752 753 if (CmsLog.INIT.isInfoEnabled()) { 754 CmsLog.INIT.info(Messages.get().getBundle().key(Messages.INIT_FILL_DEFAULTS_0)); 755 } 756 757 String adminUser = OpenCms.getDefaultUsers().getUserAdmin(); 758 CmsUser admin = m_driverManager.readUser(dbc, adminUser); 759 760 String administratorsGroup = OpenCms.getDefaultUsers().getGroupAdministrators(); 761 CmsGroup administrators = m_driverManager.readGroup(dbc, administratorsGroup); 762 763 String usersGroup = OpenCms.getDefaultUsers().getGroupUsers(); 764 CmsGroup users = m_driverManager.readGroup(dbc, usersGroup); 765 766 ///////////////////////////////////////////////////////////////////////////////////// 767 // online project stuff 768 ///////////////////////////////////////////////////////////////////////////////////// 769 770 // create the online project 771 CmsProject onlineProject = createProject( 772 dbc, 773 CmsProject.ONLINE_PROJECT_ID, 774 admin, 775 users, 776 administrators, 777 CmsProject.ONLINE_PROJECT_NAME, 778 "The Online project", 779 I_CmsPrincipal.FLAG_ENABLED, 780 CmsProject.PROJECT_TYPE_NORMAL); 781 782 // create the root-folder for the online project 783 CmsFolder rootFolder = new CmsFolder( 784 new CmsUUID(), 785 new CmsUUID(), 786 "/", 787 CmsResourceTypeFolder.RESOURCE_TYPE_ID, 788 0, 789 onlineProject.getUuid(), 790 CmsResource.STATE_CHANGED, 791 0, 792 admin.getId(), 793 0, 794 admin.getId(), 795 CmsResource.DATE_RELEASED_DEFAULT, 796 CmsResource.DATE_EXPIRED_DEFAULT, 797 0); 798 799 m_driverManager.getVfsDriver(dbc).createResource(dbc, onlineProject.getUuid(), rootFolder, null); 800 801 // important: must access through driver manager to ensure proper cascading 802 m_driverManager.getProjectDriver(dbc).createProjectResource( 803 dbc, 804 onlineProject.getUuid(), 805 rootFolder.getRootPath()); 806 807 // create the system-folder for the online project 808 CmsFolder systemFolder = new CmsFolder( 809 new CmsUUID(), 810 new CmsUUID(), 811 "/system", 812 CmsResourceTypeFolder.RESOURCE_TYPE_ID, 813 0, 814 onlineProject.getUuid(), 815 CmsResource.STATE_CHANGED, 816 0, 817 admin.getId(), 818 0, 819 admin.getId(), 820 CmsResource.DATE_RELEASED_DEFAULT, 821 CmsResource.DATE_EXPIRED_DEFAULT, 822 0); 823 824 m_driverManager.getVfsDriver(dbc).createResource(dbc, onlineProject.getUuid(), systemFolder, null); 825 826 ///////////////////////////////////////////////////////////////////////////////////// 827 // setup project stuff 828 ///////////////////////////////////////////////////////////////////////////////////// 829 830 // important: must access through driver manager to ensure proper cascading 831 CmsProject setupProject = m_driverManager.getProjectDriver(dbc).createProject( 832 dbc, 833 CmsUUID.getConstantUUID(SETUP_PROJECT_NAME), 834 admin, 835 administrators, 836 administrators, 837 SETUP_PROJECT_NAME, 838 "The Project for the initial import", 839 I_CmsPrincipal.FLAG_ENABLED, 840 CmsProject.PROJECT_TYPE_TEMPORARY); 841 842 rootFolder.setState(CmsResource.STATE_CHANGED); 843 // create the root-folder for the offline project 844 CmsResource offlineRootFolder = m_driverManager.getVfsDriver( 845 dbc).createResource(dbc, setupProject.getUuid(), rootFolder, null); 846 847 offlineRootFolder.setState(CmsResource.STATE_UNCHANGED); 848 849 m_driverManager.getVfsDriver( 850 dbc).writeResource(dbc, setupProject.getUuid(), offlineRootFolder, CmsDriverManager.NOTHING_CHANGED); 851 852 // important: must access through driver manager to ensure proper cascading 853 m_driverManager.getProjectDriver(dbc).createProjectResource( 854 dbc, 855 setupProject.getUuid(), 856 offlineRootFolder.getRootPath()); 857 858 systemFolder.setState(CmsResource.STATE_CHANGED); 859 // create the system-folder for the offline project 860 CmsResource offlineSystemFolder = m_driverManager.getVfsDriver( 861 dbc).createResource(dbc, setupProject.getUuid(), systemFolder, null); 862 863 offlineSystemFolder.setState(CmsResource.STATE_UNCHANGED); 864 865 m_driverManager.getVfsDriver( 866 dbc).writeResource(dbc, setupProject.getUuid(), offlineSystemFolder, CmsDriverManager.NOTHING_CHANGED); 867 } 868 869 /** 870 * @see org.opencms.db.I_CmsProjectDriver#getSqlManager() 871 */ 872 public CmsSqlManager getSqlManager() { 873 874 return m_sqlManager; 875 } 876 877 /** 878 * @see org.opencms.db.I_CmsProjectDriver#getUsersPubList(org.opencms.db.CmsDbContext, org.opencms.util.CmsUUID) 879 */ 880 public List<CmsResource> getUsersPubList(CmsDbContext dbc, CmsUUID userId) throws CmsDataAccessException { 881 882 List<CmsResource> result = new ArrayList<CmsResource>(); 883 Connection conn = null; 884 PreparedStatement stmt = null; 885 ResultSet res = null; 886 try { 887 conn = m_sqlManager.getConnection(dbc); 888 String sql = m_sqlManager.readQuery("C_USER_PUBLISH_LIST_READ_1"); 889 sql = sql.replace("${PROJECT}", "OFFLINE"); 890 stmt = m_sqlManager.getPreparedStatementForSql(conn, sql); 891 stmt.setString(1, userId.toString()); 892 res = stmt.executeQuery(); 893 while (res.next()) { 894 CmsResource resource = m_driverManager.getVfsDriver(dbc).createResource( 895 res, 896 dbc.currentProject().getUuid()); 897 long date = res.getLong("DATE_CHANGED"); 898 resource.setDateLastModified(date); 899 result.add(resource); 900 } 901 return result; 902 } catch (SQLException e) { 903 throw new CmsDbSqlException( 904 Messages.get().container(Messages.ERR_GENERIC_SQL_1, CmsDbSqlException.getErrorQuery(stmt)), 905 e); 906 } finally { 907 m_sqlManager.closeAll(dbc, conn, stmt, res); 908 } 909 } 910 911 /** 912 * @see org.opencms.db.I_CmsDriver#init(CmsDbContext, CmsConfigurationManager, List, CmsDriverManager) 913 */ 914 public void init( 915 CmsDbContext dbc, 916 CmsConfigurationManager configurationManager, 917 List<String> successiveDrivers, 918 CmsDriverManager driverManager) { 919 920 CmsParameterConfiguration configuration = configurationManager.getConfiguration(); 921 String poolUrl = configuration.get("db.project.pool"); 922 String classname = configuration.get("db.project.sqlmanager"); 923 m_sqlManager = initSqlManager(classname); 924 m_sqlManager.init(I_CmsProjectDriver.DRIVER_TYPE_ID, poolUrl); 925 926 m_driverManager = driverManager; 927 928 if (CmsLog.INIT.isInfoEnabled()) { 929 CmsLog.INIT.info(Messages.get().getBundle().key(Messages.INIT_ASSIGNED_POOL_1, poolUrl)); 930 } 931 932 if ((successiveDrivers != null) && !successiveDrivers.isEmpty()) { 933 if (LOG.isWarnEnabled()) { 934 LOG.warn( 935 Messages.get().getBundle().key( 936 Messages.LOG_SUCCESSIVE_DRIVERS_UNSUPPORTED_1, 937 getClass().getName())); 938 } 939 } 940 } 941 942 /** 943 * @see org.opencms.db.I_CmsProjectDriver#initSqlManager(String) 944 */ 945 public org.opencms.db.generic.CmsSqlManager initSqlManager(String classname) { 946 947 return CmsSqlManager.getInstance(classname); 948 } 949 950 /** 951 * @see org.opencms.db.I_CmsProjectDriver#log(org.opencms.db.CmsDbContext, java.util.List) 952 */ 953 public void log(CmsDbContext dbc, List<CmsLogEntry> logEntries) throws CmsDbSqlException { 954 955 Connection conn = null; 956 PreparedStatement stmt = null; 957 958 try { 959 conn = m_sqlManager.getConnection(dbc); 960 stmt = m_sqlManager.getPreparedStatement(conn, "C_LOG_CREATE_5"); 961 962 for (CmsLogEntry logEntry : logEntries) { 963 stmt.setString(1, logEntry.getUserId().toString()); 964 stmt.setLong(2, logEntry.getDate()); 965 stmt.setString(3, logEntry.getStructureId() == null ? null : logEntry.getStructureId().toString()); 966 stmt.setInt(4, logEntry.getType().getId()); 967 stmt.setString(5, CmsStringUtil.arrayAsString(logEntry.getData(), "|")); 968 try { 969 stmt.executeUpdate(); 970 } catch (SQLException e) { 971 // ignore, most likely a duplicate entry 972 LOG.debug( 973 Messages.get().container( 974 Messages.ERR_GENERIC_SQL_1, 975 CmsDbSqlException.getErrorQuery(stmt)).key(), 976 e); 977 } 978 } 979 } catch (SQLException e) { 980 throw new CmsDbSqlException( 981 Messages.get().container(Messages.ERR_GENERIC_SQL_1, CmsDbSqlException.getErrorQuery(stmt)), 982 e); 983 } finally { 984 try { 985 m_sqlManager.closeAll(dbc, conn, stmt, null); 986 } catch (Throwable t) { 987 // this could happen during shutdown 988 LOG.debug(t.getLocalizedMessage(), t); 989 } 990 } 991 } 992 993 /** 994 * @see org.opencms.db.I_CmsProjectDriver#publishDeletedFolder(org.opencms.db.CmsDbContext, org.opencms.report.I_CmsReport, int, int, org.opencms.file.CmsProject, org.opencms.file.CmsFolder, org.opencms.util.CmsUUID, int) 995 */ 996 public void publishDeletedFolder( 997 CmsDbContext dbc, 998 I_CmsReport report, 999 int m, 1000 int n, 1001 CmsProject onlineProject, 1002 CmsFolder currentFolder, 1003 CmsUUID publishHistoryId, 1004 int publishTag) 1005 throws CmsDataAccessException { 1006 1007 try { 1008 report.print( 1009 org.opencms.report.Messages.get().container( 1010 org.opencms.report.Messages.RPT_SUCCESSION_2, 1011 String.valueOf(m), 1012 String.valueOf(n)), 1013 I_CmsReport.FORMAT_NOTE); 1014 report.print(Messages.get().container(Messages.RPT_DELETE_FOLDER_0), I_CmsReport.FORMAT_NOTE); 1015 report.print( 1016 org.opencms.report.Messages.get().container( 1017 org.opencms.report.Messages.RPT_ARGUMENT_1, 1018 dbc.removeSiteRoot(currentFolder.getRootPath()))); 1019 report.print(org.opencms.report.Messages.get().container(org.opencms.report.Messages.RPT_DOTS_0)); 1020 1021 CmsResourceState folderState = fixMovedResource( 1022 dbc, 1023 onlineProject, 1024 currentFolder, 1025 publishHistoryId, 1026 publishTag); 1027 1028 // read the folder online 1029 CmsFolder onlineFolder = m_driverManager.readFolder( 1030 dbc, 1031 currentFolder.getRootPath(), 1032 CmsResourceFilter.ALL); 1033 1034 // if the folder in the online-project contains any files, these need to be removed. 1035 // this can occur if these files were moved in the offline-project 1036 List<CmsResource> movedFiles = null; 1037 I_CmsVfsDriver vfsDriver = m_driverManager.getVfsDriver(dbc); 1038 movedFiles = vfsDriver.readResourceTree( 1039 dbc, 1040 onlineProject.getUuid(), 1041 currentFolder.getRootPath(), 1042 CmsDriverManager.READ_IGNORE_TYPE, 1043 null, 1044 CmsDriverManager.READ_IGNORE_TIME, 1045 CmsDriverManager.READ_IGNORE_TIME, 1046 CmsDriverManager.READ_IGNORE_TIME, 1047 CmsDriverManager.READ_IGNORE_TIME, 1048 CmsDriverManager.READ_IGNORE_TIME, 1049 CmsDriverManager.READ_IGNORE_TIME, 1050 CmsDriverManager.READMODE_INCLUDE_TREE); 1051 1052 for (CmsResource delFile : movedFiles) { 1053 try { 1054 CmsResource offlineResource = vfsDriver.readResource( 1055 dbc, 1056 dbc.currentProject().getUuid(), 1057 delFile.getStructureId(), 1058 true); 1059 if (offlineResource.isFile()) { 1060 CmsFile offlineFile = new CmsFile(offlineResource); 1061 offlineFile.setContents( 1062 vfsDriver.readContent(dbc, dbc.currentProject().getUuid(), offlineFile.getResourceId())); 1063 internalWriteHistory( 1064 dbc, 1065 offlineFile, 1066 delFile, 1067 CmsResource.STATE_DELETED, 1068 null, 1069 publishHistoryId, 1070 publishTag); 1071 vfsDriver.deletePropertyObjects( 1072 dbc, 1073 onlineProject.getUuid(), 1074 delFile, 1075 CmsProperty.DELETE_OPTION_DELETE_STRUCTURE_AND_RESOURCE_VALUES); 1076 vfsDriver.removeFile(dbc, onlineProject.getUuid(), delFile); 1077 } else if (offlineResource.isFolder()) { 1078 1079 internalWriteHistory( 1080 dbc, 1081 offlineResource, 1082 delFile, 1083 CmsResource.STATE_DELETED, 1084 null, 1085 publishHistoryId, 1086 publishTag); 1087 vfsDriver.deletePropertyObjects( 1088 dbc, 1089 onlineProject.getUuid(), 1090 delFile, 1091 CmsProperty.DELETE_OPTION_DELETE_STRUCTURE_AND_RESOURCE_VALUES); 1092 vfsDriver.removeFolder(dbc, onlineProject, delFile); 1093 } 1094 } catch (CmsDataAccessException e) { 1095 if (LOG.isWarnEnabled()) { 1096 LOG.warn( 1097 Messages.get().getBundle().key(Messages.LOG_REMOVING_RESOURCE_1, delFile.getName()), 1098 e); 1099 } 1100 } 1101 } 1102 1103 // write history before deleting 1104 internalWriteHistory(dbc, currentFolder, null, folderState, null, publishHistoryId, publishTag); 1105 1106 try { 1107 // delete the properties online and offline 1108 vfsDriver.deletePropertyObjects( 1109 dbc, 1110 onlineProject.getUuid(), 1111 onlineFolder, 1112 CmsProperty.DELETE_OPTION_DELETE_STRUCTURE_AND_RESOURCE_VALUES); 1113 vfsDriver.deletePropertyObjects( 1114 dbc, 1115 dbc.currentProject().getUuid(), 1116 currentFolder, 1117 CmsProperty.DELETE_OPTION_DELETE_STRUCTURE_AND_RESOURCE_VALUES); 1118 } catch (CmsDataAccessException e) { 1119 if (LOG.isErrorEnabled()) { 1120 LOG.error( 1121 Messages.get().getBundle().key(Messages.LOG_DELETING_PROPERTIES_1, currentFolder.getRootPath()), 1122 e); 1123 } 1124 throw e; 1125 } 1126 1127 try { 1128 // remove the folder online and offline 1129 vfsDriver.removeFolder(dbc, dbc.currentProject(), currentFolder); 1130 vfsDriver.removeFolder(dbc, onlineProject, currentFolder); 1131 } catch (CmsDataAccessException e) { 1132 if (LOG.isErrorEnabled()) { 1133 LOG.error( 1134 Messages.get().getBundle().key(Messages.LOG_REMOVING_RESOURCE_1, currentFolder.getRootPath()), 1135 e); 1136 } 1137 throw e; 1138 } 1139 1140 try { 1141 // remove the ACL online and offline 1142 m_driverManager.getUserDriver(dbc).removeAccessControlEntries( 1143 dbc, 1144 onlineProject, 1145 onlineFolder.getResourceId()); 1146 m_driverManager.getUserDriver(dbc).removeAccessControlEntries( 1147 dbc, 1148 dbc.currentProject(), 1149 currentFolder.getResourceId()); 1150 } catch (CmsDataAccessException e) { 1151 if (LOG.isErrorEnabled()) { 1152 LOG.error( 1153 Messages.get().getBundle().key(Messages.LOG_REMOVING_ACL_1, currentFolder.getRootPath()), 1154 e); 1155 } 1156 throw e; 1157 } 1158 1159 // remove relations 1160 try { 1161 vfsDriver.deleteRelations(dbc, onlineProject.getUuid(), onlineFolder, CmsRelationFilter.TARGETS); 1162 vfsDriver.deleteRelations( 1163 dbc, 1164 dbc.currentProject().getUuid(), 1165 currentFolder, 1166 CmsRelationFilter.TARGETS); 1167 } catch (CmsDataAccessException e) { 1168 if (LOG.isErrorEnabled()) { 1169 LOG.error( 1170 Messages.get().getBundle().key(Messages.LOG_REMOVING_RELATIONS_1, currentFolder.getRootPath()), 1171 e); 1172 } 1173 throw e; 1174 } 1175 1176 // remove project resources 1177 String deletedResourceRootPath = currentFolder.getRootPath(); 1178 Iterator<CmsProject> itProjects = readProjectsForResource(dbc, deletedResourceRootPath).iterator(); 1179 while (itProjects.hasNext()) { 1180 CmsProject project = itProjects.next(); 1181 deleteProjectResource(dbc, project.getUuid(), deletedResourceRootPath); 1182 } 1183 1184 try { 1185 m_driverManager.getVfsDriver(dbc).deleteAliases( 1186 dbc, 1187 onlineProject, 1188 new CmsAliasFilter(null, null, currentFolder.getStructureId())); 1189 } catch (CmsDataAccessException e) { 1190 LOG.error("Could not delete aliases: " + e.getLocalizedMessage(), e); 1191 } 1192 1193 report.println( 1194 org.opencms.report.Messages.get().container(org.opencms.report.Messages.RPT_OK_0), 1195 I_CmsReport.FORMAT_OK); 1196 1197 if (LOG.isDebugEnabled()) { 1198 if (LOG.isDebugEnabled()) { 1199 LOG.debug( 1200 Messages.get().getBundle().key( 1201 Messages.LOG_DEL_FOLDER_3, 1202 currentFolder.getRootPath(), 1203 String.valueOf(m), 1204 String.valueOf(n))); 1205 } 1206 } 1207 } finally { 1208 // notify the app. that the published folder and it's properties have been modified offline 1209 OpenCms.fireCmsEvent( 1210 new CmsEvent( 1211 I_CmsEventListener.EVENT_RESOURCE_AND_PROPERTIES_MODIFIED, 1212 Collections.<String, Object> singletonMap(I_CmsEventListener.KEY_RESOURCE, currentFolder))); 1213 } 1214 } 1215 1216 /** 1217 * @see org.opencms.db.I_CmsProjectDriver#publishFile(org.opencms.db.CmsDbContext, org.opencms.report.I_CmsReport, int, int, org.opencms.file.CmsProject, org.opencms.file.CmsResource, java.util.Set, org.opencms.util.CmsUUID, int) 1218 */ 1219 public void publishFile( 1220 CmsDbContext dbc, 1221 I_CmsReport report, 1222 int m, 1223 int n, 1224 CmsProject onlineProject, 1225 CmsResource offlineResource, 1226 Set<CmsUUID> publishedContentIds, 1227 CmsUUID publishHistoryId, 1228 int publishTag) 1229 throws CmsDataAccessException { 1230 1231 /* 1232 * Never use onlineResource.getState() here! 1233 * Only use offlineResource.getState() to determine the state of an offline resource! 1234 * 1235 * In case a resource has siblings, after a sibling was published the structure 1236 * and resource states are reset to UNCHANGED -> the state of the corresponding 1237 * onlineResource is still NEW, DELETED or CHANGED. 1238 * Thus, using onlineResource.getState() will inevitably result in unpublished resources! 1239 */ 1240 1241 try { 1242 report.print( 1243 org.opencms.report.Messages.get().container( 1244 org.opencms.report.Messages.RPT_SUCCESSION_2, 1245 String.valueOf(m), 1246 String.valueOf(n)), 1247 I_CmsReport.FORMAT_NOTE); 1248 1249 if (offlineResource.getState().isDeleted()) { 1250 report.print(Messages.get().container(Messages.RPT_DELETE_FILE_0), I_CmsReport.FORMAT_NOTE); 1251 report.print( 1252 org.opencms.report.Messages.get().container( 1253 org.opencms.report.Messages.RPT_ARGUMENT_1, 1254 dbc.removeSiteRoot(offlineResource.getRootPath()))); 1255 report.print(org.opencms.report.Messages.get().container(org.opencms.report.Messages.RPT_DOTS_0)); 1256 1257 publishDeletedFile(dbc, onlineProject, offlineResource, publishHistoryId, publishTag); 1258 1259 dbc.pop(); 1260 List<CmsProperty> props = m_driverManager.readPropertyObjects(dbc, offlineResource, true); 1261 boolean removeDeleted = Boolean.parseBoolean( 1262 CmsProperty.get(CmsPropertyDefinition.PROPERTY_HISTORY_REMOVE_DELETED, props).getValue("false")); 1263 // delete old historical entries 1264 m_driverManager.getHistoryDriver(dbc).deleteEntries( 1265 dbc, 1266 new CmsHistoryFile(offlineResource), 1267 removeDeleted ? 0 : OpenCms.getSystemInfo().getHistoryVersionsAfterDeletion(), 1268 -1); 1269 1270 report.println( 1271 org.opencms.report.Messages.get().container(org.opencms.report.Messages.RPT_OK_0), 1272 I_CmsReport.FORMAT_OK); 1273 1274 if (LOG.isDebugEnabled()) { 1275 LOG.debug( 1276 Messages.get().getBundle().key( 1277 Messages.LOG_DEL_FILE_3, 1278 String.valueOf(m), 1279 String.valueOf(n), 1280 offlineResource.getRootPath())); 1281 } 1282 1283 } else if (offlineResource.getState().isChanged()) { 1284 report.print(Messages.get().container(Messages.RPT_PUBLISH_FILE_0), I_CmsReport.FORMAT_NOTE); 1285 report.print( 1286 org.opencms.report.Messages.get().container( 1287 org.opencms.report.Messages.RPT_ARGUMENT_1, 1288 dbc.removeSiteRoot(offlineResource.getRootPath()))); 1289 report.print(org.opencms.report.Messages.get().container(org.opencms.report.Messages.RPT_DOTS_0)); 1290 1291 publishChangedFile( 1292 dbc, 1293 onlineProject, 1294 offlineResource, 1295 publishedContentIds, 1296 publishHistoryId, 1297 publishTag); 1298 1299 dbc.pop(); 1300 // delete old historical entries 1301 m_driverManager.getHistoryDriver(dbc).deleteEntries( 1302 dbc, 1303 new CmsHistoryFile(offlineResource), 1304 OpenCms.getSystemInfo().getHistoryVersions(), 1305 -1); 1306 1307 report.println( 1308 org.opencms.report.Messages.get().container(org.opencms.report.Messages.RPT_OK_0), 1309 I_CmsReport.FORMAT_OK); 1310 1311 if (LOG.isDebugEnabled()) { 1312 LOG.debug( 1313 Messages.get().getBundle().key( 1314 Messages.LOG_PUBLISHING_FILE_3, 1315 offlineResource.getRootPath(), 1316 String.valueOf(m), 1317 String.valueOf(n))); 1318 } 1319 } else if (offlineResource.getState().isNew()) { 1320 report.print(Messages.get().container(Messages.RPT_PUBLISH_FILE_0), I_CmsReport.FORMAT_NOTE); 1321 report.print( 1322 org.opencms.report.Messages.get().container( 1323 org.opencms.report.Messages.RPT_ARGUMENT_1, 1324 dbc.removeSiteRoot(offlineResource.getRootPath()))); 1325 report.print(org.opencms.report.Messages.get().container(org.opencms.report.Messages.RPT_DOTS_0)); 1326 1327 publishNewFile(dbc, onlineProject, offlineResource, publishedContentIds, publishHistoryId, publishTag); 1328 1329 dbc.pop(); 1330 // delete old historical entries 1331 m_driverManager.getHistoryDriver(dbc).deleteEntries( 1332 dbc, 1333 new CmsHistoryFile(offlineResource), 1334 OpenCms.getSystemInfo().getHistoryVersions(), 1335 -1); 1336 1337 report.println( 1338 org.opencms.report.Messages.get().container(org.opencms.report.Messages.RPT_OK_0), 1339 I_CmsReport.FORMAT_OK); 1340 1341 if (LOG.isDebugEnabled()) { 1342 if (LOG.isDebugEnabled()) { 1343 LOG.debug( 1344 Messages.get().getBundle().key( 1345 Messages.LOG_PUBLISHING_FILE_3, 1346 offlineResource.getRootPath(), 1347 String.valueOf(m), 1348 String.valueOf(n))); 1349 } 1350 } 1351 } else { 1352 // state == unchanged !!?? something went really wrong 1353 report.print(Messages.get().container(Messages.RPT_PUBLISH_FILE_0), I_CmsReport.FORMAT_NOTE); 1354 report.print( 1355 org.opencms.report.Messages.get().container( 1356 org.opencms.report.Messages.RPT_ARGUMENT_1, 1357 dbc.removeSiteRoot(offlineResource.getRootPath()))); 1358 report.print(org.opencms.report.Messages.get().container(org.opencms.report.Messages.RPT_DOTS_0)); 1359 report.println( 1360 org.opencms.report.Messages.get().container(org.opencms.report.Messages.RPT_FAILED_0), 1361 I_CmsReport.FORMAT_ERROR); 1362 1363 if (LOG.isErrorEnabled()) { 1364 // the whole resource is printed out here 1365 LOG.error( 1366 Messages.get().getBundle().key( 1367 Messages.LOG_PUBLISHING_FILE_3, 1368 String.valueOf(m), 1369 String.valueOf(n), 1370 offlineResource)); 1371 } 1372 } 1373 m_driverManager.publishUrlNameMapping(dbc, offlineResource); 1374 if (offlineResource.getState().isDeleted()) { 1375 m_driverManager.getVfsDriver(dbc).deleteAliases( 1376 dbc, 1377 onlineProject, 1378 new CmsAliasFilter(null, null, offlineResource.getStructureId())); 1379 } 1380 } catch (CmsException e) { 1381 throw new CmsDataAccessException(e.getMessageContainer(), e); 1382 } finally { 1383 // notify the app. that the published file and it's properties have been modified offline 1384 Map<String, Object> data = new HashMap<String, Object>(2); 1385 data.put(I_CmsEventListener.KEY_RESOURCE, offlineResource); 1386 data.put(I_CmsEventListener.KEY_SKIPINDEX, Boolean.valueOf(true)); 1387 1388 OpenCms.fireCmsEvent(new CmsEvent(I_CmsEventListener.EVENT_RESOURCE_AND_PROPERTIES_MODIFIED, data)); 1389 } 1390 } 1391 1392 /** 1393 * @see org.opencms.db.I_CmsProjectDriver#publishFileContent(CmsDbContext, CmsProject, CmsProject, CmsResource, Set, boolean, int) 1394 */ 1395 public CmsFile publishFileContent( 1396 CmsDbContext dbc, 1397 CmsProject offlineProject, 1398 CmsProject onlineProject, 1399 CmsResource offlineResource, 1400 Set<CmsUUID> publishedResourceIds, 1401 boolean needToUpdateContent, 1402 int publishTag) 1403 throws CmsDataAccessException { 1404 1405 CmsFile newFile = null; 1406 try { 1407 // read the file content offline 1408 CmsUUID projectId = dbc.getProjectId(); 1409 boolean dbcHasProjectId = (projectId != null) && !projectId.isNullUUID(); 1410 CmsUUID projectIdForReading = (!dbcHasProjectId ? offlineProject.getUuid() : CmsProject.ONLINE_PROJECT_ID); 1411 dbc.setProjectId(offlineProject.getUuid()); 1412 byte[] offlineContent = m_driverManager.getVfsDriver(dbc).readContent( 1413 dbc, 1414 projectIdForReading, 1415 offlineResource.getResourceId()); 1416 CmsFile offlineFile = new CmsFile(offlineResource); 1417 offlineFile.setContents(offlineContent); 1418 dbc.setProjectId(projectId); 1419 1420 // create the file online 1421 newFile = (CmsFile)offlineFile.clone(); 1422 newFile.setState(CmsResource.STATE_UNCHANGED); 1423 1424 boolean createSibling = true; 1425 // check if we are facing with a create new sibling operation 1426 if (!offlineFile.getState().isNew()) { 1427 createSibling = false; 1428 } else { 1429 // check if the resource entry already exists 1430 if (!m_driverManager.getVfsDriver(dbc).validateResourceIdExists( 1431 dbc, 1432 onlineProject.getUuid(), 1433 offlineFile.getResourceId())) { 1434 // we are creating a normal resource and not a sibling 1435 createSibling = false; 1436 } 1437 } 1438 1439 // only update the content if it was not updated before 1440 boolean alreadyPublished = publishedResourceIds.contains(offlineResource.getResourceId()); 1441 needToUpdateContent &= !alreadyPublished; 1442 1443 if (createSibling) { 1444 if (!alreadyPublished) { 1445 // create the file online, the first time a sibling is published also the resource entry has to be actualized 1446 m_driverManager.getVfsDriver(dbc).createResource(dbc, onlineProject.getUuid(), newFile, null); 1447 } else { 1448 // create the sibling online 1449 m_driverManager.getVfsDriver(dbc).createSibling(dbc, onlineProject, offlineResource); 1450 } 1451 newFile = new CmsFile(offlineResource); 1452 newFile.setContents(offlineContent); 1453 } else { 1454 // update the online/offline structure and resource records of the file 1455 m_driverManager.getVfsDriver(dbc).publishResource(dbc, onlineProject, newFile, offlineFile); 1456 } 1457 // update version numbers 1458 m_driverManager.getVfsDriver(dbc).publishVersions(dbc, offlineResource, !alreadyPublished); 1459 1460 // create/update the content 1461 m_driverManager.getVfsDriver(dbc).createOnlineContent( 1462 dbc, 1463 offlineFile.getResourceId(), 1464 offlineFile.getContents(), 1465 publishTag, 1466 true, 1467 needToUpdateContent); 1468 1469 // mark the resource as written to avoid that the same content is written for each sibling instance 1470 publishedResourceIds.add(offlineResource.getResourceId()); 1471 } catch (CmsDataAccessException e) { 1472 if (LOG.isErrorEnabled()) { 1473 LOG.error( 1474 Messages.get().getBundle().key(Messages.LOG_PUBLISHING_FILE_CONTENT_1, offlineResource.toString()), 1475 e); 1476 } 1477 throw e; 1478 } 1479 return newFile; 1480 } 1481 1482 /** 1483 * @see org.opencms.db.I_CmsProjectDriver#publishFolder(org.opencms.db.CmsDbContext, org.opencms.report.I_CmsReport, int, int, org.opencms.file.CmsProject, org.opencms.file.CmsFolder, org.opencms.util.CmsUUID, int) 1484 */ 1485 public void publishFolder( 1486 CmsDbContext dbc, 1487 I_CmsReport report, 1488 int m, 1489 int n, 1490 CmsProject onlineProject, 1491 CmsFolder offlineFolder, 1492 CmsUUID publishHistoryId, 1493 int publishTag) 1494 throws CmsDataAccessException { 1495 1496 try { 1497 report.print( 1498 org.opencms.report.Messages.get().container( 1499 org.opencms.report.Messages.RPT_SUCCESSION_2, 1500 String.valueOf(m), 1501 String.valueOf(n)), 1502 I_CmsReport.FORMAT_NOTE); 1503 report.print(Messages.get().container(Messages.RPT_PUBLISH_FOLDER_0), I_CmsReport.FORMAT_NOTE); 1504 report.print( 1505 org.opencms.report.Messages.get().container( 1506 org.opencms.report.Messages.RPT_ARGUMENT_1, 1507 dbc.removeSiteRoot(offlineFolder.getRootPath()))); 1508 report.print(org.opencms.report.Messages.get().container(org.opencms.report.Messages.RPT_DOTS_0)); 1509 1510 CmsResourceState resourceState = fixMovedResource( 1511 dbc, 1512 onlineProject, 1513 offlineFolder, 1514 publishHistoryId, 1515 publishTag); 1516 1517 CmsResource onlineFolder = null; 1518 if (offlineFolder.getState().isNew()) { 1519 try { 1520 // create the folder online 1521 CmsResource newFolder = (CmsFolder)offlineFolder.clone(); 1522 newFolder.setState(CmsResource.STATE_UNCHANGED); 1523 1524 onlineFolder = m_driverManager.getVfsDriver( 1525 dbc).createResource(dbc, onlineProject.getUuid(), newFolder, null); 1526 m_driverManager.getVfsDriver(dbc).publishResource(dbc, onlineProject, onlineFolder, offlineFolder); 1527 // update version numbers 1528 m_driverManager.getVfsDriver(dbc).publishVersions(dbc, offlineFolder, true); 1529 } catch (CmsVfsResourceAlreadyExistsException e) { 1530 if (!offlineFolder.getRootPath().equals("/") 1531 && !offlineFolder.getRootPath().equals("/system/") 1532 && LOG.isWarnEnabled()) { 1533 LOG.warn( 1534 Messages.get().getBundle().key( 1535 Messages.LOG_WARN_FOLDER_WRONG_STATE_CN_1, 1536 offlineFolder.getRootPath())); 1537 } 1538 try { 1539 onlineFolder = m_driverManager.getVfsDriver(dbc).readFolder( 1540 dbc, 1541 onlineProject.getUuid(), 1542 offlineFolder.getRootPath()); 1543 m_driverManager.getVfsDriver( 1544 dbc).publishResource(dbc, onlineProject, onlineFolder, offlineFolder); 1545 // update version numbers 1546 m_driverManager.getVfsDriver(dbc).publishVersions(dbc, offlineFolder, true); 1547 } catch (CmsDataAccessException e1) { 1548 if (LOG.isErrorEnabled()) { 1549 LOG.error( 1550 Messages.get().getBundle().key( 1551 Messages.LOG_READING_RESOURCE_1, 1552 offlineFolder.getRootPath()), 1553 e); 1554 } 1555 throw e1; 1556 } 1557 } catch (CmsDataAccessException e) { 1558 if (LOG.isErrorEnabled()) { 1559 LOG.error( 1560 Messages.get().getBundle().key( 1561 Messages.LOG_PUBLISHING_RESOURCE_1, 1562 offlineFolder.getRootPath()), 1563 e); 1564 } 1565 throw e; 1566 } 1567 } else if (offlineFolder.getState().isChanged()) { 1568 try { 1569 // read the folder online 1570 onlineFolder = m_driverManager.getVfsDriver(dbc).readFolder( 1571 dbc, 1572 onlineProject.getUuid(), 1573 offlineFolder.getStructureId()); 1574 } catch (CmsVfsResourceNotFoundException e) { 1575 if (LOG.isWarnEnabled()) { 1576 LOG.warn( 1577 Messages.get().getBundle().key( 1578 Messages.LOG_WARN_FOLDER_WRONG_STATE_NC_1, 1579 offlineFolder.getRootPath())); 1580 } 1581 try { 1582 onlineFolder = m_driverManager.getVfsDriver( 1583 dbc).createResource(dbc, onlineProject.getUuid(), offlineFolder, null); 1584 internalResetResourceState(dbc, onlineFolder); 1585 } catch (CmsDataAccessException e1) { 1586 if (LOG.isErrorEnabled()) { 1587 LOG.error( 1588 Messages.get().getBundle().key( 1589 Messages.LOG_PUBLISHING_RESOURCE_1, 1590 offlineFolder.getRootPath()), 1591 e); 1592 } 1593 throw e1; 1594 } 1595 } 1596 1597 try { 1598 // update the folder online 1599 m_driverManager.getVfsDriver(dbc).publishResource(dbc, onlineProject, onlineFolder, offlineFolder); 1600 // update version numbers 1601 m_driverManager.getVfsDriver(dbc).publishVersions(dbc, offlineFolder, true); 1602 } catch (CmsDataAccessException e) { 1603 if (LOG.isErrorEnabled()) { 1604 LOG.error( 1605 Messages.get().getBundle().key( 1606 Messages.LOG_PUBLISHING_RESOURCE_1, 1607 offlineFolder.getRootPath()), 1608 e); 1609 } 1610 throw e; 1611 } 1612 } 1613 1614 if (onlineFolder != null) { 1615 try { 1616 // write the ACL online 1617 m_driverManager.getUserDriver(dbc).publishAccessControlEntries( 1618 dbc, 1619 dbc.currentProject(), 1620 onlineProject, 1621 offlineFolder.getResourceId(), 1622 onlineFolder.getResourceId()); 1623 } catch (CmsDataAccessException e) { 1624 if (LOG.isErrorEnabled()) { 1625 LOG.error( 1626 Messages.get().getBundle().key(Messages.LOG_PUBLISHING_ACL_1, offlineFolder.getRootPath()), 1627 e); 1628 } 1629 throw e; 1630 } 1631 } 1632 1633 List<CmsProperty> offlineProperties = null; 1634 try { 1635 // write the properties online 1636 m_driverManager.getVfsDriver(dbc).deletePropertyObjects( 1637 dbc, 1638 onlineProject.getUuid(), 1639 onlineFolder, 1640 CmsProperty.DELETE_OPTION_DELETE_STRUCTURE_AND_RESOURCE_VALUES); 1641 offlineProperties = m_driverManager.getVfsDriver(dbc).readPropertyObjects( 1642 dbc, 1643 dbc.currentProject(), 1644 offlineFolder); 1645 CmsProperty.setAutoCreatePropertyDefinitions(offlineProperties, true); 1646 m_driverManager.getVfsDriver( 1647 dbc).writePropertyObjects(dbc, onlineProject, onlineFolder, offlineProperties); 1648 } catch (CmsDataAccessException e) { 1649 if (LOG.isErrorEnabled()) { 1650 LOG.error( 1651 Messages.get().getBundle().key( 1652 Messages.LOG_PUBLISHING_PROPERTIES_1, 1653 offlineFolder.getRootPath()), 1654 e); 1655 } 1656 throw e; 1657 } 1658 1659 internalWriteHistory( 1660 dbc, 1661 offlineFolder, 1662 null, 1663 resourceState, 1664 offlineProperties, 1665 publishHistoryId, 1666 publishTag); 1667 1668 m_driverManager.getVfsDriver(dbc).updateRelations(dbc, onlineProject, offlineFolder); 1669 1670 report.println( 1671 org.opencms.report.Messages.get().container(org.opencms.report.Messages.RPT_OK_0), 1672 I_CmsReport.FORMAT_OK); 1673 1674 if (LOG.isDebugEnabled()) { 1675 LOG.debug( 1676 Messages.get().getBundle().key( 1677 Messages.LOG_PUBLISHING_FOLDER_3, 1678 String.valueOf(m), 1679 String.valueOf(n), 1680 offlineFolder.getRootPath())); 1681 } 1682 } finally { 1683 // notify the app. that the published folder and it's properties have been modified offline 1684 OpenCms.fireCmsEvent( 1685 new CmsEvent( 1686 I_CmsEventListener.EVENT_RESOURCE_AND_PROPERTIES_MODIFIED, 1687 Collections.<String, Object> singletonMap(I_CmsEventListener.KEY_RESOURCE, offlineFolder))); 1688 } 1689 } 1690 1691 /** 1692 * @see org.opencms.db.I_CmsProjectDriver#publishProject(org.opencms.db.CmsDbContext, org.opencms.report.I_CmsReport, org.opencms.file.CmsProject, org.opencms.db.CmsPublishList, int) 1693 */ 1694 public void publishProject( 1695 CmsDbContext dbc, 1696 I_CmsReport report, 1697 CmsProject onlineProject, 1698 CmsPublishList publishList, 1699 int publishTag) 1700 throws CmsException { 1701 1702 int publishedFolderCount = 0; 1703 int deletedFolderCount = 0; 1704 int publishedFileCount = 0; 1705 Set<CmsUUID> publishedContentIds = new HashSet<CmsUUID>(); 1706 Set<CmsUUID> publishedIds = new HashSet<CmsUUID>(); 1707 1708 try { 1709 1710 ///////////////////////////////////////////////////////////////////////////////// 1711 // write the historical project entry 1712 1713 if (OpenCms.getSystemInfo().isHistoryEnabled()) { 1714 try { 1715 // write an entry in the publish project log 1716 m_driverManager.getHistoryDriver(dbc).writeProject(dbc, publishTag, System.currentTimeMillis()); 1717 dbc.pop(); 1718 } catch (Throwable t) { 1719 dbc.report( 1720 report, 1721 Messages.get().container( 1722 Messages.ERR_WRITING_HISTORY_OF_PROJECT_1, 1723 dbc.currentProject().getName()), 1724 t); 1725 } 1726 } 1727 1728 //////////////////////////////////////////////////////////////////////////////// 1729 // publish new/changed folders 1730 1731 if (LOG.isDebugEnabled()) { 1732 LOG.debug( 1733 Messages.get().getBundle().key( 1734 Messages.LOG_START_PUBLISHING_PROJECT_2, 1735 dbc.currentProject().getName(), 1736 dbc.currentUser().getName())); 1737 } 1738 1739 publishedFolderCount = 0; 1740 int foldersSize = publishList.getFolderList().size(); 1741 if (foldersSize > 0) { 1742 report.println( 1743 Messages.get().container(Messages.RPT_PUBLISH_FOLDERS_BEGIN_0), 1744 I_CmsReport.FORMAT_HEADLINE); 1745 } 1746 1747 Iterator<CmsResource> itFolders = publishList.getFolderList().iterator(); 1748 I_CmsProjectDriver projectDriver = m_driverManager.getProjectDriver(dbc); 1749 I_CmsHistoryDriver historyDriver = m_driverManager.getHistoryDriver(dbc); 1750 while (itFolders.hasNext()) { 1751 CmsResource currentFolder = itFolders.next(); 1752 try { 1753 if (currentFolder.getState().isNew() || currentFolder.getState().isChanged()) { 1754 // bounce the current publish task through all project drivers 1755 projectDriver.publishFolder( 1756 dbc, 1757 report, 1758 ++publishedFolderCount, 1759 foldersSize, 1760 onlineProject, 1761 new CmsFolder(currentFolder), 1762 publishList.getPublishHistoryId(), 1763 publishTag); 1764 1765 dbc.pop(); 1766 1767 publishedIds.add(currentFolder.getStructureId()); 1768 // log it 1769 CmsLogEntryType type = currentFolder.getState().isNew() 1770 ? CmsLogEntryType.RESOURCE_PUBLISHED_NEW 1771 : CmsLogEntryType.RESOURCE_PUBLISHED_MODIFIED; 1772 m_driverManager.log( 1773 dbc, 1774 new CmsLogEntry( 1775 dbc, 1776 currentFolder.getStructureId(), 1777 type, 1778 new String[] {currentFolder.getRootPath()}), 1779 true); 1780 1781 // delete old historical entries 1782 historyDriver.deleteEntries( 1783 dbc, 1784 new CmsHistoryFile(currentFolder), 1785 OpenCms.getSystemInfo().getHistoryVersions(), 1786 -1); 1787 1788 // reset the resource state to UNCHANGED and the last-modified-in-project-ID to 0 1789 internalResetResourceState(dbc, currentFolder); 1790 1791 if (!CmsModificationContext.isInOnlineFolder(currentFolder.getRootPath())) { 1792 m_driverManager.unlockResource(dbc, currentFolder, true, true); 1793 } 1794 } else { 1795 // state == unchanged !!?? something went really wrong 1796 report.print(Messages.get().container(Messages.RPT_PUBLISH_FOLDER_0), I_CmsReport.FORMAT_NOTE); 1797 report.print( 1798 org.opencms.report.Messages.get().container( 1799 org.opencms.report.Messages.RPT_ARGUMENT_1, 1800 dbc.removeSiteRoot(currentFolder.getRootPath()))); 1801 report.print( 1802 org.opencms.report.Messages.get().container(org.opencms.report.Messages.RPT_DOTS_0)); 1803 report.println( 1804 org.opencms.report.Messages.get().container(org.opencms.report.Messages.RPT_FAILED_0), 1805 I_CmsReport.FORMAT_ERROR); 1806 1807 if (LOG.isErrorEnabled()) { 1808 // the whole resource is printed out here 1809 LOG.error( 1810 Messages.get().getBundle().key( 1811 Messages.LOG_PUBLISHING_FILE_3, 1812 String.valueOf(++publishedFolderCount), 1813 String.valueOf(foldersSize), 1814 currentFolder)); 1815 } 1816 } 1817 1818 dbc.pop(); 1819 } catch (Throwable t) { 1820 dbc.report( 1821 report, 1822 Messages.get().container(Messages.ERR_ERROR_PUBLISHING_FOLDER_1, currentFolder.getRootPath()), 1823 t); 1824 } 1825 } 1826 1827 if (foldersSize > 0) { 1828 report.println( 1829 Messages.get().container(Messages.RPT_PUBLISH_FOLDERS_END_0), 1830 I_CmsReport.FORMAT_HEADLINE); 1831 } 1832 1833 //////////////////////////////////////////////////////////////////////////////// 1834 // publish changed/new/deleted files 1835 1836 publishedFileCount = 0; 1837 int filesSize = publishList.getFileList().size(); 1838 1839 if (filesSize > 0) { 1840 report.println( 1841 Messages.get().container(Messages.RPT_PUBLISH_FILES_BEGIN_0), 1842 I_CmsReport.FORMAT_HEADLINE); 1843 } 1844 1845 Set<CmsUUID> deletedResourceIds = new HashSet<CmsUUID>(); 1846 Set<CmsUUID> changedResourceIds = new HashSet<CmsUUID>(); 1847 for (CmsResource res : publishList.getFileList()) { 1848 if (res.getState().isDeleted()) { 1849 deletedResourceIds.add(res.getResourceId()); 1850 } else { 1851 changedResourceIds.add(res.getResourceId()); 1852 } 1853 } 1854 Set<CmsUUID> changedAndDeletedResourceIds = Sets.intersection(deletedResourceIds, changedResourceIds); 1855 dbc.setAttribute(CmsDriverManager.KEY_CHANGED_AND_DELETED, changedAndDeletedResourceIds); 1856 1857 Iterator<CmsResource> itFiles = publishList.getFileList().iterator(); 1858 while (itFiles.hasNext()) { 1859 CmsResource currentResource = itFiles.next(); 1860 try { 1861 // bounce the current publish task through all project drivers 1862 projectDriver.publishFile( 1863 dbc, 1864 report, 1865 ++publishedFileCount, 1866 filesSize, 1867 onlineProject, 1868 currentResource, 1869 publishedContentIds, 1870 publishList.getPublishHistoryId(), 1871 publishTag); 1872 1873 CmsResourceState state = currentResource.getState(); 1874 if (!state.isDeleted()) { 1875 // reset the resource state to UNCHANGED and the last-modified-in-project-ID to 0 1876 internalResetResourceState(dbc, currentResource); 1877 } 1878 1879 // unlock it 1880 if (!CmsModificationContext.isInOnlineFolder(currentResource.getRootPath())) { 1881 m_driverManager.unlockResource(dbc, currentResource, true, true); 1882 } 1883 // log it 1884 CmsLogEntryType type = state.isNew() 1885 ? CmsLogEntryType.RESOURCE_PUBLISHED_NEW 1886 : (state.isDeleted() 1887 ? CmsLogEntryType.RESOURCE_PUBLISHED_DELETED 1888 : CmsLogEntryType.RESOURCE_PUBLISHED_MODIFIED); 1889 m_driverManager.log( 1890 dbc, 1891 new CmsLogEntry( 1892 dbc, 1893 currentResource.getStructureId(), 1894 type, 1895 new String[] {currentResource.getRootPath()}), 1896 true); 1897 1898 publishedIds.add(currentResource.getStructureId()); 1899 dbc.pop(); 1900 } catch (Throwable t) { 1901 dbc.report( 1902 report, 1903 Messages.get().container(Messages.ERR_ERROR_PUBLISHING_FILE_1, currentResource.getRootPath()), 1904 t); 1905 } 1906 } 1907 1908 if (filesSize > 0) { 1909 report.println(Messages.get().container(Messages.RPT_PUBLISH_FILES_END_0), I_CmsReport.FORMAT_HEADLINE); 1910 } 1911 1912 ///////////////////////////////////////////////////////////////////////////////// 1913 1914 // publish deleted folders 1915 List<CmsResource> deletedFolders = publishList.getDeletedFolderList(); 1916 if (deletedFolders.isEmpty()) { 1917 return; 1918 } 1919 1920 deletedFolderCount = 0; 1921 int deletedFoldersSize = deletedFolders.size(); 1922 if (deletedFoldersSize > 0) { 1923 report.println( 1924 Messages.get().container(Messages.RPT_DELETE_FOLDERS_BEGIN_0), 1925 I_CmsReport.FORMAT_HEADLINE); 1926 } 1927 1928 Iterator<CmsResource> itDeletedFolders = deletedFolders.iterator(); 1929 while (itDeletedFolders.hasNext()) { 1930 CmsResource currentFolder = itDeletedFolders.next(); 1931 1932 try { 1933 // bounce the current publish task through all project drivers 1934 projectDriver.publishDeletedFolder( 1935 dbc, 1936 report, 1937 ++deletedFolderCount, 1938 deletedFoldersSize, 1939 onlineProject, 1940 new CmsFolder(currentFolder), 1941 publishList.getPublishHistoryId(), 1942 publishTag); 1943 1944 dbc.pop(); 1945 // delete old historical entries 1946 m_driverManager.getHistoryDriver(dbc).deleteEntries( 1947 dbc, 1948 new CmsHistoryFile(currentFolder), 1949 OpenCms.getSystemInfo().getHistoryVersionsAfterDeletion(), 1950 -1); 1951 1952 publishedIds.add(currentFolder.getStructureId()); 1953 // unlock it 1954 if (!CmsModificationContext.isInOnlineFolder(currentFolder.getRootPath())) { 1955 m_driverManager.unlockResource(dbc, currentFolder, true, true); 1956 } 1957 // log it 1958 m_driverManager.log( 1959 dbc, 1960 new CmsLogEntry( 1961 dbc, 1962 currentFolder.getStructureId(), 1963 CmsLogEntryType.RESOURCE_PUBLISHED_DELETED, 1964 new String[] {currentFolder.getRootPath()}), 1965 true); 1966 1967 dbc.pop(); 1968 } catch (Throwable t) { 1969 dbc.report( 1970 report, 1971 Messages.get().container( 1972 Messages.ERR_ERROR_PUBLISHING_DELETED_FOLDER_1, 1973 currentFolder.getRootPath()), 1974 t); 1975 } 1976 } 1977 1978 if (deletedFoldersSize > 0) { 1979 report.println( 1980 Messages.get().container(Messages.RPT_DELETE_FOLDERS_END_0), 1981 I_CmsReport.FORMAT_HEADLINE); 1982 } 1983 } catch (OutOfMemoryError o) { 1984 // clear all caches to reclaim memory 1985 OpenCms.fireCmsEvent( 1986 new CmsEvent(I_CmsEventListener.EVENT_CLEAR_CACHES, Collections.<String, Object> emptyMap())); 1987 1988 CmsMessageContainer message = Messages.get().container(Messages.ERR_OUT_OF_MEMORY_0); 1989 if (LOG.isErrorEnabled()) { 1990 LOG.error(message.key(), o); 1991 } 1992 throw new CmsDataAccessException(message, o); 1993 } finally { 1994 // reset vfs driver internal info after publishing 1995 m_driverManager.getVfsDriver(dbc).publishVersions(dbc, null, false); 1996 Object[] msgArgs = new Object[] { 1997 String.valueOf(publishedFileCount), 1998 String.valueOf(publishedFolderCount), 1999 String.valueOf(deletedFolderCount), 2000 report.formatRuntime()}; 2001 2002 CmsMessageContainer message = Messages.get().container(Messages.RPT_PUBLISH_STAT_4, msgArgs); 2003 if (LOG.isInfoEnabled()) { 2004 LOG.info(message.key()); 2005 } 2006 report.println(message); 2007 } 2008 } 2009 2010 /** 2011 * @see org.opencms.db.I_CmsProjectDriver#readLocks(org.opencms.db.CmsDbContext) 2012 */ 2013 public List<CmsLock> readLocks(CmsDbContext dbc) throws CmsDataAccessException { 2014 2015 Connection conn = null; 2016 PreparedStatement stmt = null; 2017 List<CmsTempResourceLock> tmpLocks = new ArrayList<CmsTempResourceLock>(256); 2018 List<CmsLock> locks = new ArrayList<CmsLock>(256); 2019 try { 2020 conn = m_sqlManager.getConnection(dbc); 2021 stmt = m_sqlManager.getPreparedStatement(conn, "C_RESOURCE_LOCKS_READALL"); 2022 ResultSet rs = stmt.executeQuery(); 2023 while (rs.next()) { 2024 String resourcePath = rs.getString(m_sqlManager.readQuery("C_RESOURCE_LOCKS_RESOURCE_PATH")); 2025 CmsUUID userId = new CmsUUID(rs.getString(m_sqlManager.readQuery("C_RESOURCE_LOCKS_USER_ID"))); 2026 CmsUUID projectId = new CmsUUID(rs.getString(m_sqlManager.readQuery("C_RESOURCE_LOCKS_PROJECT_ID"))); 2027 int lockType = rs.getInt(m_sqlManager.readQuery("C_RESOURCE_LOCKS_LOCK_TYPE")); 2028 CmsTempResourceLock tmpLock = new CmsTempResourceLock(resourcePath, userId, projectId, lockType); 2029 tmpLocks.add(tmpLock); 2030 } 2031 } catch (SQLException e) { 2032 throw new CmsDbSqlException( 2033 Messages.get().container(Messages.ERR_GENERIC_SQL_1, CmsDbSqlException.getErrorQuery(stmt)), 2034 e); 2035 } finally { 2036 m_sqlManager.closeAll(dbc, conn, stmt, null); 2037 } 2038 2039 for (CmsTempResourceLock tmpLock : tmpLocks) { 2040 CmsProject project; 2041 try { 2042 project = readProject(dbc, tmpLock.getProjectId()); 2043 } catch (CmsDataAccessException dae) { 2044 // the project does not longer exist, ignore this lock (should usually not happen) 2045 project = null; 2046 } 2047 if (project != null) { 2048 CmsLock lock = new CmsLock( 2049 tmpLock.getResourcePath(), 2050 tmpLock.getUserId(), 2051 project, 2052 CmsLockType.valueOf(tmpLock.getLockType())); 2053 locks.add(lock); 2054 } 2055 } 2056 if (LOG.isDebugEnabled()) { 2057 LOG.debug(Messages.get().getBundle().key(Messages.LOG_DBG_READ_LOCKS_1, Integer.valueOf(locks.size()))); 2058 } 2059 return locks; 2060 } 2061 2062 /** 2063 * @see org.opencms.db.I_CmsProjectDriver#readLog(org.opencms.db.CmsDbContext, org.opencms.db.log.CmsLogFilter) 2064 */ 2065 public List<CmsLogEntry> readLog(CmsDbContext dbc, CmsLogFilter filter) throws CmsDataAccessException { 2066 2067 List<CmsLogEntry> entries = new ArrayList<CmsLogEntry>(); 2068 2069 Connection conn = null; 2070 PreparedStatement stmt = null; 2071 ResultSet res = null; 2072 2073 try { 2074 conn = m_sqlManager.getConnection(dbc); 2075 // compose statement 2076 StringBuffer queryBuf = new StringBuffer(256); 2077 queryBuf.append(m_sqlManager.readQuery("C_LOG_READ_ENTRIES")); 2078 CmsPair<String, List<I_CmsPreparedStatementParameter>> conditionsAndParameters = prepareLogConditions( 2079 filter); 2080 List<I_CmsPreparedStatementParameter> params = conditionsAndParameters.getSecond(); 2081 queryBuf.append(conditionsAndParameters.getFirst()); 2082 2083 if (LOG.isDebugEnabled()) { 2084 LOG.debug(queryBuf.toString()); 2085 } 2086 stmt = m_sqlManager.getPreparedStatementForSql(conn, queryBuf.toString()); 2087 for (int i = 0; i < params.size(); i++) { 2088 I_CmsPreparedStatementParameter param = params.get(i); 2089 param.insertIntoStatement(stmt, i + 1); 2090 } 2091 2092 // execute 2093 res = stmt.executeQuery(); 2094 while (res.next()) { 2095 // get results 2096 entries.add(internalReadLogEntry(res)); 2097 } 2098 } catch (SQLException e) { 2099 throw new CmsDbSqlException( 2100 Messages.get().container(Messages.ERR_GENERIC_SQL_1, CmsDbSqlException.getErrorQuery(stmt)), 2101 e); 2102 } finally { 2103 m_sqlManager.closeAll(dbc, conn, stmt, res); 2104 } 2105 return entries; 2106 } 2107 2108 /** 2109 * @see org.opencms.db.I_CmsProjectDriver#readProject(org.opencms.db.CmsDbContext, CmsUUID) 2110 */ 2111 public CmsProject readProject(CmsDbContext dbc, CmsUUID id) throws CmsDataAccessException { 2112 2113 PreparedStatement stmt = null; 2114 CmsProject project = null; 2115 ResultSet res = null; 2116 Connection conn = null; 2117 2118 try { 2119 conn = m_sqlManager.getConnection(dbc); 2120 stmt = m_sqlManager.getPreparedStatement(conn, "C_PROJECTS_READ_1"); 2121 2122 stmt.setString(1, id.toString()); 2123 res = stmt.executeQuery(); 2124 2125 if (res.next()) { 2126 project = internalCreateProject(res); 2127 while (res.next()) { 2128 // do nothing only move through all rows because of mssql odbc driver 2129 } 2130 } else { 2131 throw new CmsDbEntryNotFoundException( 2132 Messages.get().container(Messages.ERR_NO_PROJECT_WITH_ID_1, String.valueOf(id))); 2133 } 2134 } catch (SQLException e) { 2135 throw new CmsDbSqlException( 2136 Messages.get().container(Messages.ERR_GENERIC_SQL_1, CmsDbSqlException.getErrorQuery(stmt)), 2137 e); 2138 } finally { 2139 m_sqlManager.closeAll(dbc, conn, stmt, res); 2140 } 2141 2142 return project; 2143 } 2144 2145 /** 2146 * @see org.opencms.db.I_CmsProjectDriver#readProject(org.opencms.db.CmsDbContext, java.lang.String) 2147 */ 2148 public CmsProject readProject(CmsDbContext dbc, String projectFqn) throws CmsDataAccessException { 2149 2150 PreparedStatement stmt = null; 2151 CmsProject project = null; 2152 ResultSet res = null; 2153 Connection conn = null; 2154 2155 try { 2156 conn = m_sqlManager.getConnection(dbc); 2157 stmt = m_sqlManager.getPreparedStatement(conn, "C_PROJECTS_READ_BYNAME_2"); 2158 2159 stmt.setString(1, CmsOrganizationalUnit.getSimpleName(projectFqn)); 2160 stmt.setString(2, CmsOrganizationalUnit.SEPARATOR + CmsOrganizationalUnit.getParentFqn(projectFqn)); 2161 res = stmt.executeQuery(); 2162 2163 if (res.next()) { 2164 project = internalCreateProject(res); 2165 while (res.next()) { 2166 // do nothing only move through all rows because of mssql odbc driver 2167 } 2168 } else { 2169 throw new CmsDbEntryNotFoundException( 2170 Messages.get().container(Messages.ERR_NO_PROJECT_WITH_NAME_1, projectFqn)); 2171 } 2172 } catch (SQLException e) { 2173 throw new CmsDbSqlException( 2174 Messages.get().container(Messages.ERR_GENERIC_SQL_1, CmsDbSqlException.getErrorQuery(stmt)), 2175 e); 2176 } finally { 2177 m_sqlManager.closeAll(dbc, conn, stmt, res); 2178 } 2179 2180 return project; 2181 } 2182 2183 /** 2184 * @see org.opencms.db.I_CmsProjectDriver#readProjectResource(org.opencms.db.CmsDbContext, CmsUUID, java.lang.String) 2185 */ 2186 public String readProjectResource(CmsDbContext dbc, CmsUUID projectId, String resourcePath) 2187 throws CmsDataAccessException { 2188 2189 PreparedStatement stmt = null; 2190 Connection conn = null; 2191 ResultSet res = null; 2192 String resName = null; 2193 2194 try { 2195 conn = getSqlManager().getConnection(dbc); 2196 stmt = m_sqlManager.getPreparedStatement(conn, "C_PROJECTRESOURCES_READ_2"); 2197 2198 // select resource from the database 2199 stmt.setString(1, projectId.toString()); 2200 stmt.setString(2, resourcePath); 2201 res = stmt.executeQuery(); 2202 2203 if (res.next()) { 2204 resName = res.getString("RESOURCE_PATH"); 2205 while (res.next()) { 2206 // do nothing only move through all rows because of mssql odbc driver 2207 } 2208 } else { 2209 throw new CmsVfsResourceNotFoundException( 2210 Messages.get().container(Messages.ERR_NO_PROJECTRESOURCE_1, resourcePath)); 2211 } 2212 } catch (SQLException e) { 2213 throw new CmsDbSqlException( 2214 Messages.get().container(Messages.ERR_GENERIC_SQL_1, CmsDbSqlException.getErrorQuery(stmt)), 2215 e); 2216 } finally { 2217 m_sqlManager.closeAll(dbc, conn, stmt, res); 2218 } 2219 return resName; 2220 } 2221 2222 /** 2223 * @see org.opencms.db.I_CmsProjectDriver#readProjectResources(org.opencms.db.CmsDbContext, org.opencms.file.CmsProject) 2224 */ 2225 public List<String> readProjectResources(CmsDbContext dbc, CmsProject project) throws CmsDataAccessException { 2226 2227 PreparedStatement stmt = null; 2228 Connection conn = null; 2229 ResultSet res = null; 2230 List<String> result = new ArrayList<String>(); 2231 2232 try { 2233 conn = m_sqlManager.getConnection(dbc); 2234 stmt = m_sqlManager.getPreparedStatement(conn, "C_PROJECTRESOURCES_READ_BY_ID_1"); 2235 stmt.setString(1, project.getUuid().toString()); 2236 res = stmt.executeQuery(); 2237 2238 while (res.next()) { 2239 result.add(res.getString("RESOURCE_PATH")); 2240 } 2241 } catch (SQLException e) { 2242 throw new CmsDbSqlException( 2243 Messages.get().container(Messages.ERR_GENERIC_SQL_1, CmsDbSqlException.getErrorQuery(stmt)), 2244 e); 2245 } finally { 2246 m_sqlManager.closeAll(dbc, conn, stmt, res); 2247 } 2248 2249 return result; 2250 } 2251 2252 /** 2253 * @see org.opencms.db.I_CmsProjectDriver#readProjects(org.opencms.db.CmsDbContext, String) 2254 */ 2255 public List<CmsProject> readProjects(CmsDbContext dbc, String ouFqn) throws CmsDataAccessException { 2256 2257 if ((dbc.getRequestContext() != null) 2258 && (dbc.getRequestContext().getAttribute(DBC_ATTR_READ_PROJECT_FOR_RESOURCE) != null)) { 2259 dbc.getRequestContext().removeAttribute(DBC_ATTR_READ_PROJECT_FOR_RESOURCE); 2260 // TODO: this should get its own method in the interface 2261 return readProjectsForResource(dbc, ouFqn); 2262 } 2263 List<CmsProject> projects = new ArrayList<CmsProject>(); 2264 ResultSet res = null; 2265 PreparedStatement stmt = null; 2266 Connection conn = null; 2267 2268 try { 2269 // create the statement 2270 conn = m_sqlManager.getConnection(dbc); 2271 stmt = m_sqlManager.getPreparedStatement(conn, "C_PROJECTS_READ_BYOU_1"); 2272 2273 stmt.setString(1, CmsOrganizationalUnit.SEPARATOR + ouFqn + "%"); 2274 res = stmt.executeQuery(); 2275 2276 while (res.next()) { 2277 projects.add(internalCreateProject(res)); 2278 } 2279 } catch (SQLException e) { 2280 throw new CmsDbSqlException( 2281 Messages.get().container(Messages.ERR_GENERIC_SQL_1, CmsDbSqlException.getErrorQuery(stmt)), 2282 e); 2283 } finally { 2284 m_sqlManager.closeAll(dbc, conn, stmt, res); 2285 } 2286 2287 return (projects); 2288 } 2289 2290 /** 2291 * @see org.opencms.db.I_CmsProjectDriver#readProjectsForGroup(org.opencms.db.CmsDbContext, org.opencms.file.CmsGroup) 2292 */ 2293 public List<CmsProject> readProjectsForGroup(CmsDbContext dbc, CmsGroup group) throws CmsDataAccessException { 2294 2295 List<CmsProject> projects = new ArrayList<CmsProject>(); 2296 ResultSet res = null; 2297 Connection conn = null; 2298 PreparedStatement stmt = null; 2299 2300 try { 2301 // create the statement 2302 conn = m_sqlManager.getConnection(dbc); 2303 stmt = m_sqlManager.getPreparedStatement(conn, "C_PROJECTS_READ_BYGROUP_2"); 2304 2305 stmt.setString(1, group.getId().toString()); 2306 stmt.setString(2, group.getId().toString()); 2307 res = stmt.executeQuery(); 2308 2309 while (res.next()) { 2310 projects.add(internalCreateProject(res)); 2311 } 2312 } catch (SQLException e) { 2313 throw new CmsDbSqlException( 2314 Messages.get().container(Messages.ERR_GENERIC_SQL_1, CmsDbSqlException.getErrorQuery(stmt)), 2315 e); 2316 } finally { 2317 m_sqlManager.closeAll(dbc, conn, stmt, res); 2318 } 2319 return (projects); 2320 } 2321 2322 /** 2323 * @see org.opencms.db.I_CmsProjectDriver#readProjectsForManagerGroup(org.opencms.db.CmsDbContext, org.opencms.file.CmsGroup) 2324 */ 2325 public List<CmsProject> readProjectsForManagerGroup(CmsDbContext dbc, CmsGroup group) 2326 throws CmsDataAccessException { 2327 2328 List<CmsProject> projects = new ArrayList<CmsProject>(); 2329 ResultSet res = null; 2330 PreparedStatement stmt = null; 2331 Connection conn = null; 2332 2333 try { 2334 // create the statement 2335 conn = m_sqlManager.getConnection(dbc); 2336 stmt = m_sqlManager.getPreparedStatement(conn, "C_PROJECTS_READ_BYMANAGER_1"); 2337 2338 stmt.setString(1, group.getId().toString()); 2339 res = stmt.executeQuery(); 2340 2341 while (res.next()) { 2342 projects.add(internalCreateProject(res)); 2343 } 2344 } catch (SQLException e) { 2345 throw new CmsDbSqlException( 2346 Messages.get().container(Messages.ERR_GENERIC_SQL_1, CmsDbSqlException.getErrorQuery(stmt)), 2347 e); 2348 } finally { 2349 m_sqlManager.closeAll(dbc, conn, stmt, res); 2350 } 2351 return (projects); 2352 } 2353 2354 /** 2355 * Returns the projects of a given resource.<p> 2356 * 2357 * @param dbc the database context 2358 * @param rootPath the resource root path 2359 * 2360 * @return the projects of the resource, as a list of projects 2361 * 2362 * @throws CmsDataAccessException if something goes wrong 2363 */ 2364 public List<CmsProject> readProjectsForResource(CmsDbContext dbc, String rootPath) throws CmsDataAccessException { 2365 2366 PreparedStatement stmt = null; 2367 List<CmsProject> projects = new ArrayList<CmsProject>(); 2368 ResultSet res = null; 2369 Connection conn = null; 2370 2371 try { 2372 conn = m_sqlManager.getConnection(dbc); 2373 stmt = m_sqlManager.getPreparedStatement(conn, "C_PROJECTS_READ_BYRESOURCE_1"); 2374 2375 stmt.setString(1, rootPath + "%"); 2376 res = stmt.executeQuery(); 2377 2378 if (res.next()) { 2379 projects.add(internalCreateProject(res)); 2380 while (res.next()) { 2381 // do nothing only move through all rows because of mssql odbc driver 2382 } 2383 } 2384 } catch (SQLException e) { 2385 throw new CmsDbSqlException( 2386 Messages.get().container(Messages.ERR_GENERIC_SQL_1, CmsDbSqlException.getErrorQuery(stmt)), 2387 e); 2388 } finally { 2389 m_sqlManager.closeAll(dbc, conn, stmt, res); 2390 } 2391 2392 return projects; 2393 } 2394 2395 /** 2396 * @see org.opencms.db.I_CmsProjectDriver#readProjectsForUser(org.opencms.db.CmsDbContext, org.opencms.file.CmsUser) 2397 */ 2398 public List<CmsProject> readProjectsForUser(CmsDbContext dbc, CmsUser user) throws CmsDataAccessException { 2399 2400 List<CmsProject> projects = new ArrayList<CmsProject>(); 2401 ResultSet res = null; 2402 PreparedStatement stmt = null; 2403 Connection conn = null; 2404 2405 try { 2406 // create the statement 2407 conn = m_sqlManager.getConnection(dbc); 2408 stmt = m_sqlManager.getPreparedStatement(conn, "C_PROJECTS_READ_BYUSER_1"); 2409 2410 stmt.setString(1, user.getId().toString()); 2411 res = stmt.executeQuery(); 2412 2413 while (res.next()) { 2414 projects.add(internalCreateProject(res)); 2415 } 2416 } catch (SQLException e) { 2417 throw new CmsDbSqlException( 2418 Messages.get().container(Messages.ERR_GENERIC_SQL_1, CmsDbSqlException.getErrorQuery(stmt)), 2419 e); 2420 } finally { 2421 m_sqlManager.closeAll(dbc, conn, stmt, res); 2422 } 2423 return (projects); 2424 } 2425 2426 /** 2427 * @see org.opencms.db.I_CmsProjectDriver#readPublishedResources(org.opencms.db.CmsDbContext, org.opencms.util.CmsUUID) 2428 */ 2429 public List<CmsPublishedResource> readPublishedResources(CmsDbContext dbc, CmsUUID publishHistoryId) 2430 throws CmsDataAccessException { 2431 2432 Connection conn = null; 2433 PreparedStatement stmt = null; 2434 ResultSet res = null; 2435 List<CmsPublishedResource> publishedResources = new ArrayList<CmsPublishedResource>(); 2436 2437 try { 2438 conn = m_sqlManager.getConnection(dbc); 2439 stmt = m_sqlManager.getPreparedStatement(conn, "C_SELECT_PUBLISHED_RESOURCES"); 2440 stmt.setString(1, publishHistoryId.toString()); 2441 res = stmt.executeQuery(); 2442 2443 while (res.next()) { 2444 CmsUUID structureId = new CmsUUID(res.getString("STRUCTURE_ID")); 2445 CmsUUID resourceId = new CmsUUID(res.getString("RESOURCE_ID")); 2446 String rootPath = res.getString("RESOURCE_PATH"); 2447 int resourceState = res.getInt("RESOURCE_STATE"); 2448 int resourceType = res.getInt("RESOURCE_TYPE"); 2449 int siblingCount = res.getInt("SIBLING_COUNT"); 2450 int publishTag = res.getInt("PUBLISH_TAG"); 2451 2452 // compose the resource state 2453 CmsResourceState state; 2454 if (resourceState == CmsPublishedResource.STATE_MOVED_SOURCE.getState()) { 2455 state = CmsPublishedResource.STATE_MOVED_SOURCE; 2456 } else if (resourceState == CmsPublishedResource.STATE_MOVED_DESTINATION.getState()) { 2457 state = CmsPublishedResource.STATE_MOVED_DESTINATION; 2458 } else { 2459 state = CmsResourceState.valueOf(resourceState); 2460 } 2461 2462 publishedResources.add( 2463 new CmsPublishedResource( 2464 structureId, 2465 resourceId, 2466 publishTag, 2467 rootPath, 2468 resourceType, 2469 structureId.isNullUUID() ? false : CmsFolder.isFolderType(resourceType), 2470 state, 2471 siblingCount)); 2472 } 2473 } catch (SQLException e) { 2474 throw new CmsDbSqlException( 2475 Messages.get().container(Messages.ERR_GENERIC_SQL_1, CmsDbSqlException.getErrorQuery(stmt)), 2476 e); 2477 } finally { 2478 m_sqlManager.closeAll(dbc, conn, stmt, res); 2479 } 2480 2481 return publishedResources; 2482 } 2483 2484 /** 2485 * @see org.opencms.db.I_CmsProjectDriver#readPublishJob(org.opencms.db.CmsDbContext, org.opencms.util.CmsUUID) 2486 */ 2487 public CmsPublishJobInfoBean readPublishJob(CmsDbContext dbc, CmsUUID publishHistoryId) 2488 throws CmsDataAccessException { 2489 2490 Connection conn = null; 2491 PreparedStatement stmt = null; 2492 ResultSet res = null; 2493 2494 CmsPublishJobInfoBean result = null; 2495 try { 2496 conn = m_sqlManager.getConnection(dbc); 2497 stmt = m_sqlManager.getPreparedStatement(conn, "C_PUBLISHJOB_READ_JOB"); 2498 stmt.setString(1, publishHistoryId.toString()); 2499 res = stmt.executeQuery(); 2500 2501 if (res.next()) { 2502 result = createPublishJobInfoBean(res); 2503 while (res.next()) { 2504 // do nothing only move through all rows because of mssql odbc driver 2505 } 2506 } else { 2507 throw new CmsDbEntryNotFoundException( 2508 Messages.get().container(Messages.ERR_READ_PUBLISH_JOB_1, publishHistoryId.toString())); 2509 } 2510 } catch (SQLException e) { 2511 throw new CmsDbSqlException( 2512 Messages.get().container(Messages.ERR_GENERIC_SQL_1, CmsDbSqlException.getErrorQuery(stmt)), 2513 e); 2514 } finally { 2515 m_sqlManager.closeAll(dbc, conn, stmt, res); 2516 } 2517 2518 return result; 2519 } 2520 2521 /** 2522 * @see org.opencms.db.I_CmsProjectDriver#readPublishJobs(org.opencms.db.CmsDbContext, long, long) 2523 */ 2524 public List<CmsPublishJobInfoBean> readPublishJobs(CmsDbContext dbc, long startTime, long endTime) 2525 throws CmsDataAccessException { 2526 2527 Connection conn = null; 2528 PreparedStatement stmt = null; 2529 ResultSet res = null; 2530 2531 List<CmsPublishJobInfoBean> result = null; 2532 try { 2533 conn = m_sqlManager.getConnection(dbc); 2534 stmt = m_sqlManager.getPreparedStatement(conn, "C_PUBLISHJOB_READ_JOBS_IN_TIMERANGE"); 2535 stmt.setLong(1, startTime); 2536 stmt.setLong(2, endTime); 2537 res = stmt.executeQuery(); 2538 2539 result = new ArrayList<CmsPublishJobInfoBean>(); 2540 while (res.next()) { 2541 result.add(createPublishJobInfoBean(res)); 2542 } 2543 } catch (SQLException e) { 2544 throw new CmsDbSqlException( 2545 Messages.get().container(Messages.ERR_GENERIC_SQL_1, CmsDbSqlException.getErrorQuery(stmt)), 2546 e); 2547 } finally { 2548 m_sqlManager.closeAll(dbc, conn, stmt, res); 2549 } 2550 2551 return result; 2552 } 2553 2554 /** 2555 * @see org.opencms.db.I_CmsProjectDriver#readPublishList(org.opencms.db.CmsDbContext, org.opencms.util.CmsUUID) 2556 */ 2557 public CmsPublishList readPublishList(CmsDbContext dbc, CmsUUID publishHistoryId) throws CmsDataAccessException { 2558 2559 Connection conn = null; 2560 PreparedStatement stmt = null; 2561 ResultSet res = null; 2562 CmsPublishList publishList = null; 2563 2564 try { 2565 conn = m_sqlManager.getConnection(dbc); 2566 stmt = m_sqlManager.getPreparedStatement(conn, "C_PUBLISHJOB_READ_PUBLISHLIST"); 2567 stmt.setString(1, publishHistoryId.toString()); 2568 res = stmt.executeQuery(); 2569 2570 if (res.next()) { 2571 byte[] bytes = m_sqlManager.getBytes(res, "PUBLISH_LIST"); 2572 publishList = internalDeserializePublishList(bytes); 2573 while (res.next()) { 2574 // do nothing only move through all rows because of mssql odbc driver 2575 } 2576 } else { 2577 throw new CmsDataAccessException( 2578 Messages.get().container(Messages.ERR_READ_PUBLISH_JOB_1, publishHistoryId.toString())); 2579 } 2580 } catch (SQLException e) { 2581 throw new CmsDbSqlException( 2582 Messages.get().container(Messages.ERR_GENERIC_SQL_1, CmsDbSqlException.getErrorQuery(stmt)), 2583 e); 2584 } catch (Exception e) { 2585 throw new CmsDataAccessException( 2586 Messages.get().container(Messages.ERR_PUBLISHLIST_DESERIALIZATION_FAILED_1, publishHistoryId), 2587 e); 2588 } finally { 2589 m_sqlManager.closeAll(dbc, conn, stmt, res); 2590 } 2591 2592 return publishList; 2593 } 2594 2595 /** 2596 * @see org.opencms.db.I_CmsProjectDriver#readPublishReportContents(org.opencms.db.CmsDbContext, org.opencms.util.CmsUUID) 2597 */ 2598 public byte[] readPublishReportContents(CmsDbContext dbc, CmsUUID publishHistoryId) throws CmsDataAccessException { 2599 2600 PreparedStatement stmt = null; 2601 ResultSet res = null; 2602 Connection conn = null; 2603 byte[] bytes = null; 2604 2605 try { 2606 conn = m_sqlManager.getConnection(dbc); 2607 2608 stmt = m_sqlManager.getPreparedStatement(conn, "C_PUBLISHJOB_READ_REPORT"); 2609 stmt.setString(1, publishHistoryId.toString()); 2610 res = stmt.executeQuery(); 2611 2612 if (res.next()) { 2613 // query to read Array of bytes for the given attribute 2614 bytes = m_sqlManager.getBytes(res, "PUBLISH_REPORT"); 2615 while (res.next()) { 2616 // do nothing only move through all rows because of mssql odbc driver 2617 } 2618 } else { 2619 throw new CmsDataAccessException( 2620 Messages.get().container(Messages.ERR_READ_PUBLISH_JOB_1, publishHistoryId.toString())); 2621 } 2622 } catch (SQLException e) { 2623 LOG.error(CmsDbSqlException.getErrorQuery(stmt), e); 2624 bytes = Messages.get().container( 2625 Messages.ERR_GENERIC_SQL_1, 2626 CmsDbSqlException.getErrorQuery(stmt)).key().getBytes(); 2627 } finally { 2628 m_sqlManager.closeAll(dbc, conn, stmt, res); 2629 } 2630 return bytes; 2631 } 2632 2633 /** 2634 * @see org.opencms.db.I_CmsProjectDriver#readStaticExportPublishedResourceParameters(org.opencms.db.CmsDbContext, java.lang.String) 2635 */ 2636 public String readStaticExportPublishedResourceParameters(CmsDbContext dbc, String rfsName) 2637 throws CmsDataAccessException { 2638 2639 String returnValue = null; 2640 Connection conn = null; 2641 PreparedStatement stmt = null; 2642 ResultSet res = null; 2643 2644 try { 2645 conn = m_sqlManager.getConnection(dbc); 2646 stmt = m_sqlManager.getPreparedStatement(conn, "C_STATICEXPORT_READ_PUBLISHED_LINK_PARAMETERS"); 2647 stmt.setString(1, rfsName); 2648 res = stmt.executeQuery(); 2649 // add all resourcenames to the list of return values 2650 if (res.next()) { 2651 returnValue = res.getString(1); 2652 while (res.next()) { 2653 // do nothing only move through all rows because of mssql odbc driver 2654 } 2655 } 2656 } catch (SQLException e) { 2657 throw new CmsDbSqlException( 2658 Messages.get().container(Messages.ERR_GENERIC_SQL_1, CmsDbSqlException.getErrorQuery(stmt)), 2659 e); 2660 } finally { 2661 m_sqlManager.closeAll(dbc, conn, stmt, res); 2662 } 2663 2664 return returnValue; 2665 } 2666 2667 /** 2668 * @see org.opencms.db.I_CmsProjectDriver#readStaticExportResources(org.opencms.db.CmsDbContext, int, long) 2669 */ 2670 public List<String> readStaticExportResources(CmsDbContext dbc, int parameterResources, long timestamp) 2671 throws CmsDataAccessException { 2672 2673 Connection conn = null; 2674 PreparedStatement stmt = null; 2675 ResultSet res = null; 2676 List<String> returnValue = new ArrayList<String>(); 2677 2678 if (parameterResources == CmsStaticExportManager.EXPORT_LINK_WITHOUT_PARAMETER) { 2679 timestamp = 0; 2680 } 2681 try { 2682 conn = m_sqlManager.getConnection(dbc); 2683 stmt = m_sqlManager.getPreparedStatement(conn, "C_STATICEXPORT_READ_ALL_PUBLISHED_LINKS"); 2684 stmt.setInt(1, parameterResources); 2685 stmt.setLong(2, timestamp); 2686 res = stmt.executeQuery(); 2687 // add all resourcenames to the list of return values 2688 while (res.next()) { 2689 returnValue.add(res.getString(1)); 2690 } 2691 } catch (SQLException e) { 2692 throw new CmsDbSqlException( 2693 Messages.get().container(Messages.ERR_GENERIC_SQL_1, CmsDbSqlException.getErrorQuery(stmt)), 2694 e); 2695 } finally { 2696 m_sqlManager.closeAll(dbc, conn, stmt, res); 2697 } 2698 2699 return returnValue; 2700 } 2701 2702 /** 2703 * @see org.opencms.db.I_CmsProjectDriver#setDriverManager(org.opencms.db.CmsDriverManager) 2704 */ 2705 public void setDriverManager(CmsDriverManager driverManager) { 2706 2707 m_driverManager = driverManager; 2708 } 2709 2710 /** 2711 * @see org.opencms.db.I_CmsProjectDriver#setSqlManager(org.opencms.db.CmsSqlManager) 2712 */ 2713 public void setSqlManager(org.opencms.db.CmsSqlManager manager) { 2714 2715 m_sqlManager = (CmsSqlManager)manager; 2716 } 2717 2718 /** 2719 * @see org.opencms.db.I_CmsProjectDriver#unmarkProjectResources(org.opencms.db.CmsDbContext, org.opencms.file.CmsProject) 2720 */ 2721 public void unmarkProjectResources(CmsDbContext dbc, CmsProject project) throws CmsDataAccessException { 2722 2723 // finally remove the project id form all resources 2724 2725 Connection conn = null; 2726 PreparedStatement stmt = null; 2727 try { 2728 conn = m_sqlManager.getConnection(dbc); 2729 stmt = m_sqlManager.getPreparedStatement(conn, "C_RESOURCES_UNMARK"); 2730 // create the statement 2731 stmt.setString(1, project.getUuid().toString()); 2732 stmt.executeUpdate(); 2733 } catch (SQLException e) { 2734 throw new CmsDbSqlException( 2735 Messages.get().container(Messages.ERR_GENERIC_SQL_1, CmsDbSqlException.getErrorQuery(stmt)), 2736 e); 2737 } finally { 2738 m_sqlManager.closeAll(dbc, conn, stmt, null); 2739 } 2740 } 2741 2742 /** 2743 * @see org.opencms.db.I_CmsProjectDriver#writeLocks(org.opencms.db.CmsDbContext, java.util.List) 2744 */ 2745 public void writeLocks(CmsDbContext dbc, List<CmsLock> locks) throws CmsDataAccessException { 2746 2747 Connection conn = null; 2748 PreparedStatement stmt = null; 2749 try { 2750 conn = m_sqlManager.getConnection(dbc); 2751 stmt = m_sqlManager.getPreparedStatement(conn, "C_RESOURCE_LOCKS_DELETEALL"); 2752 int deleted = stmt.executeUpdate(); 2753 if (LOG.isDebugEnabled()) { 2754 LOG.debug(Messages.get().getBundle().key(Messages.LOG_DBG_CLEAR_LOCKS_1, Integer.valueOf(deleted))); 2755 } 2756 stmt = m_sqlManager.getPreparedStatement(conn, "C_RESOURCE_LOCK_WRITE"); 2757 if (LOG.isDebugEnabled()) { 2758 LOG.debug("SQL :" + m_sqlManager.readQuery("C_RESOURCE_LOCK_WRITE")); 2759 } 2760 Iterator<CmsLock> i = locks.iterator(); 2761 int count = 0; 2762 while (i.hasNext()) { 2763 CmsLock lock = i.next(); 2764 // only persist locks that should be written to the DB 2765 CmsLock sysLock = lock.getSystemLock(); 2766 if (sysLock.isPersistent()) { 2767 // persist system lock 2768 stmt.setString(1, sysLock.getResourceName()); 2769 stmt.setString(2, sysLock.getUserId().toString()); 2770 stmt.setString(3, sysLock.getProjectId().toString()); 2771 stmt.setInt(4, sysLock.getType().hashCode()); 2772 stmt.executeUpdate(); 2773 count++; 2774 } 2775 CmsLock editLock = lock.getEditionLock(); 2776 if (editLock.isPersistent()) { 2777 // persist edition lock 2778 stmt.setString(1, editLock.getResourceName()); 2779 stmt.setString(2, editLock.getUserId().toString()); 2780 stmt.setString(3, editLock.getProjectId().toString()); 2781 stmt.setInt(4, editLock.getType().hashCode()); 2782 stmt.executeUpdate(); 2783 count++; 2784 } 2785 } 2786 if (LOG.isDebugEnabled()) { 2787 LOG.debug(Messages.get().getBundle().key(Messages.LOG_DBG_WRITE_LOCKS_1, Integer.valueOf(count))); 2788 } 2789 } catch (SQLException e) { 2790 throw new CmsDbSqlException( 2791 Messages.get().container(Messages.ERR_GENERIC_SQL_1, CmsDbSqlException.getErrorQuery(stmt)), 2792 e); 2793 } finally { 2794 m_sqlManager.closeAll(dbc, conn, stmt, null); 2795 } 2796 } 2797 2798 /** 2799 * @see org.opencms.db.I_CmsProjectDriver#writeProject(org.opencms.db.CmsDbContext, org.opencms.file.CmsProject) 2800 */ 2801 public void writeProject(CmsDbContext dbc, CmsProject project) throws CmsDataAccessException { 2802 2803 if (CmsStringUtil.isEmptyOrWhitespaceOnly(project.getDescription())) { 2804 project.setDescription(" "); 2805 } 2806 Connection conn = null; 2807 PreparedStatement stmt = null; 2808 2809 try { 2810 // get a JDBC connection from the OpenCms standard pools 2811 conn = m_sqlManager.getConnection(dbc); 2812 2813 stmt = m_sqlManager.getPreparedStatement(conn, "C_PROJECTS_WRITE_6"); 2814 stmt.setString(1, project.getDescription()); 2815 stmt.setString(2, project.getGroupId().toString()); 2816 stmt.setString(3, project.getManagerGroupId().toString()); 2817 stmt.setInt(4, project.getFlags()); 2818 stmt.setInt(5, project.getType().getMode()); 2819 stmt.setString(6, project.getUuid().toString()); 2820 stmt.executeUpdate(); 2821 } catch (SQLException e) { 2822 throw new CmsDbSqlException( 2823 Messages.get().container(Messages.ERR_GENERIC_SQL_1, CmsDbSqlException.getErrorQuery(stmt)), 2824 e); 2825 } finally { 2826 m_sqlManager.closeAll(dbc, conn, stmt, null); 2827 } 2828 } 2829 2830 /** 2831 * @see org.opencms.db.I_CmsProjectDriver#writePublishHistory(org.opencms.db.CmsDbContext, org.opencms.util.CmsUUID, org.opencms.db.CmsPublishedResource) 2832 */ 2833 public void writePublishHistory(CmsDbContext dbc, CmsUUID publishId, CmsPublishedResource resource) 2834 throws CmsDataAccessException { 2835 2836 Connection conn = null; 2837 PreparedStatement stmt = null; 2838 2839 try { 2840 conn = m_sqlManager.getConnection(dbc); 2841 stmt = m_sqlManager.getPreparedStatement(conn, "C_RESOURCES_WRITE_PUBLISH_HISTORY"); 2842 stmt.setInt(1, resource.getPublishTag()); 2843 stmt.setString(2, resource.getStructureId().toString()); 2844 stmt.setString(3, resource.getResourceId().toString()); 2845 stmt.setString(4, resource.getRootPath()); 2846 stmt.setInt(5, resource.getMovedState().getState()); 2847 stmt.setInt(6, resource.getType()); 2848 stmt.setString(7, publishId.toString()); 2849 stmt.setInt(8, resource.getSiblingCount()); 2850 stmt.executeUpdate(); 2851 } catch (SQLException e) { 2852 throw new CmsDbSqlException( 2853 Messages.get().container(Messages.ERR_GENERIC_SQL_1, CmsDbSqlException.getErrorQuery(stmt)), 2854 e); 2855 } finally { 2856 m_sqlManager.closeAll(dbc, conn, stmt, null); 2857 } 2858 } 2859 2860 /** 2861 * @see org.opencms.db.I_CmsProjectDriver#writePublishJob(org.opencms.db.CmsDbContext, org.opencms.publish.CmsPublishJobInfoBean) 2862 */ 2863 public void writePublishJob(CmsDbContext dbc, CmsPublishJobInfoBean publishJob) throws CmsDataAccessException { 2864 2865 Connection conn = null; 2866 PreparedStatement stmt = null; 2867 2868 try { 2869 conn = m_sqlManager.getConnection(dbc); 2870 stmt = m_sqlManager.getPreparedStatement(conn, "C_PUBLISHJOB_WRITE"); 2871 stmt.setString(1, publishJob.getProjectId().toString()); 2872 stmt.setString(2, publishJob.getProjectName()); 2873 stmt.setString(3, publishJob.getUserId().toString()); 2874 stmt.setString(4, publishJob.getLocale().toString()); 2875 stmt.setInt(5, publishJob.getFlags()); 2876 stmt.setInt(6, publishJob.getSize()); 2877 stmt.setLong(7, publishJob.getEnqueueTime()); 2878 stmt.setLong(8, publishJob.getStartTime()); 2879 stmt.setLong(9, publishJob.getFinishTime()); 2880 stmt.setString(10, publishJob.getPublishHistoryId().toString()); 2881 stmt.executeUpdate(); 2882 } catch (SQLException e) { 2883 throw new CmsDbSqlException( 2884 Messages.get().container(Messages.ERR_GENERIC_SQL_1, CmsDbSqlException.getErrorQuery(stmt)), 2885 e); 2886 } finally { 2887 m_sqlManager.closeAll(dbc, conn, stmt, null); 2888 } 2889 } 2890 2891 /** 2892 * @see org.opencms.db.I_CmsProjectDriver#writePublishReport(org.opencms.db.CmsDbContext, org.opencms.util.CmsUUID, byte[]) 2893 */ 2894 public void writePublishReport(CmsDbContext dbc, CmsUUID publishId, byte[] content) throws CmsDataAccessException { 2895 2896 Connection conn = null; 2897 PreparedStatement stmt = null; 2898 2899 try { 2900 conn = m_sqlManager.getConnection(dbc); 2901 stmt = m_sqlManager.getPreparedStatement(conn, "C_PUBLISHJOB_WRITE_REPORT"); 2902 2903 if (content.length < 2000) { 2904 stmt.setBytes(1, content); 2905 } else { 2906 stmt.setBinaryStream(1, new ByteArrayInputStream(content), content.length); 2907 } 2908 2909 stmt.setString(2, publishId.toString()); 2910 stmt.executeUpdate(); 2911 } catch (SQLException e) { 2912 throw new CmsDbSqlException( 2913 Messages.get().container(Messages.ERR_GENERIC_SQL_1, CmsDbSqlException.getErrorQuery(stmt)), 2914 e); 2915 } finally { 2916 m_sqlManager.closeAll(dbc, conn, stmt, null); 2917 } 2918 } 2919 2920 /** 2921 * @see org.opencms.db.I_CmsProjectDriver#writeStaticExportPublishedResource(org.opencms.db.CmsDbContext, java.lang.String, int, java.lang.String, long) 2922 */ 2923 public void writeStaticExportPublishedResource( 2924 CmsDbContext dbc, 2925 String resourceName, 2926 int linkType, 2927 String linkParameter, 2928 long timestamp) 2929 throws CmsDataAccessException { 2930 2931 Connection conn = null; 2932 PreparedStatement stmt = null; 2933 ResultSet res = null; 2934 int returnValue = 0; 2935 // first check if a record with this resource name does already exist 2936 try { 2937 conn = m_sqlManager.getConnection(dbc); 2938 stmt = m_sqlManager.getPreparedStatement(conn, "C_STATICEXPORT_READ_PUBLISHED_RESOURCES"); 2939 stmt.setString(1, resourceName); 2940 res = stmt.executeQuery(); 2941 if (res.next()) { 2942 returnValue = res.getInt(1); 2943 while (res.next()) { 2944 // do nothing only move through all rows because of mssql odbc driver 2945 } 2946 } 2947 } catch (SQLException e) { 2948 throw new CmsDbSqlException( 2949 Messages.get().container(Messages.ERR_GENERIC_SQL_1, CmsDbSqlException.getErrorQuery(stmt)), 2950 e); 2951 } finally { 2952 m_sqlManager.closeAll(dbc, conn, stmt, res); 2953 } 2954 2955 // there was no entry found, so add it to the database 2956 if (returnValue == 0) { 2957 try { 2958 conn = m_sqlManager.getConnection(dbc); 2959 stmt = m_sqlManager.getPreparedStatement(conn, "C_STATICEXPORT_WRITE_PUBLISHED_LINKS"); 2960 stmt.setString(1, new CmsUUID().toString()); 2961 stmt.setString(2, resourceName); 2962 stmt.setInt(3, linkType); 2963 stmt.setString(4, linkParameter); 2964 stmt.setLong(5, timestamp); 2965 stmt.executeUpdate(); 2966 } catch (SQLException e) { 2967 throw new CmsDbSqlException(Messages.get().container(Messages.ERR_GENERIC_SQL_1, stmt), e); 2968 } finally { 2969 m_sqlManager.closeAll(dbc, conn, stmt, null); 2970 } 2971 } 2972 } 2973 2974 /** 2975 * @see org.opencms.db.I_CmsProjectDriver#writeUserPublishListEntries(org.opencms.db.CmsDbContext, java.util.List) 2976 */ 2977 public void writeUserPublishListEntries(CmsDbContext dbc, List<CmsUserPublishListEntry> publishListAdditions) 2978 throws CmsDbSqlException { 2979 2980 if (publishListAdditions.isEmpty()) { 2981 return; 2982 } 2983 2984 // first remove all entries with the same keys 2985 deleteUserPublishListEntries(dbc, publishListAdditions); 2986 2987 Connection conn = null; 2988 PreparedStatement stmt = null; 2989 try { 2990 conn = m_sqlManager.getConnection(dbc); 2991 String sql = m_sqlManager.readQuery("C_USER_PUBLISH_LIST_INSERT_3"); 2992 stmt = m_sqlManager.getPreparedStatementForSql(conn, sql); 2993 for (CmsUserPublishListEntry entry : publishListAdditions) { 2994 stmt.setString(1, entry.getUserId().toString()); 2995 stmt.setString(2, entry.getStructureId().toString()); 2996 stmt.setLong(3, entry.getDateChanged()); 2997 stmt.addBatch(); 2998 } 2999 stmt.executeBatch(); 3000 } catch (SQLException e) { 3001 throw new CmsDbSqlException( 3002 Messages.get().container(Messages.ERR_GENERIC_SQL_1, CmsDbSqlException.getErrorQuery(stmt)), 3003 e); 3004 } finally { 3005 m_sqlManager.closeAll(dbc, conn, stmt, null); 3006 } 3007 3008 } 3009 3010 /** 3011 * Creates a <code>CmsPublishJobInfoBean</code> from a result set.<p> 3012 * 3013 * @param res the result set 3014 * @return an initialized <code>CmsPublishJobInfoBean</code> 3015 * @throws SQLException if something goes wrong 3016 */ 3017 protected CmsPublishJobInfoBean createPublishJobInfoBean(ResultSet res) throws SQLException { 3018 3019 return new CmsPublishJobInfoBean( 3020 new CmsUUID(res.getString("HISTORY_ID")), 3021 new CmsUUID(res.getString("PROJECT_ID")), 3022 res.getString("PROJECT_NAME"), 3023 new CmsUUID(res.getString("USER_ID")), 3024 res.getString("PUBLISH_LOCALE"), 3025 res.getInt("PUBLISH_FLAGS"), 3026 res.getInt("RESOURCE_COUNT"), 3027 res.getLong("ENQUEUE_TIME"), 3028 res.getLong("START_TIME"), 3029 res.getLong("FINISH_TIME")); 3030 } 3031 3032 /** 3033 * Checks if the given resource (by id) is available in the online project, 3034 * if there exists a resource with a different path (a moved file), then the 3035 * online entry is moved to the right (new) location before publishing.<p> 3036 * 3037 * @param dbc the db context 3038 * @param onlineProject the online project 3039 * @param offlineResource the offline resource to check 3040 * @param publishHistoryId the publish history id 3041 * @param publishTag the publish tag 3042 * 3043 * @return <code>true</code> if the resource has actually been moved 3044 * 3045 * @throws CmsDataAccessException if something goes wrong 3046 */ 3047 protected CmsResourceState fixMovedResource( 3048 CmsDbContext dbc, 3049 CmsProject onlineProject, 3050 CmsResource offlineResource, 3051 CmsUUID publishHistoryId, 3052 int publishTag) 3053 throws CmsDataAccessException { 3054 3055 CmsResource onlineResource; 3056 // check if the resource has been moved since last publishing 3057 try { 3058 onlineResource = m_driverManager.getVfsDriver( 3059 dbc).readResource(dbc, onlineProject.getUuid(), offlineResource.getStructureId(), true); 3060 if (onlineResource.getRootPath().equals(offlineResource.getRootPath())) { 3061 // resource changed, not moved 3062 return offlineResource.getState(); 3063 } 3064 } catch (CmsVfsResourceNotFoundException e) { 3065 // ok, resource new, not moved 3066 return offlineResource.getState(); 3067 } 3068 3069 // move the online resource to the new position 3070 m_driverManager.getVfsDriver( 3071 dbc).moveResource(dbc, onlineProject.getUuid(), onlineResource, offlineResource.getRootPath()); 3072 3073 try { 3074 // write the resource to the publish history 3075 m_driverManager.getProjectDriver(dbc).writePublishHistory( 3076 dbc, 3077 publishHistoryId, 3078 new CmsPublishedResource(onlineResource, publishTag, CmsPublishedResource.STATE_MOVED_SOURCE)); 3079 } catch (CmsDataAccessException e) { 3080 if (LOG.isErrorEnabled()) { 3081 LOG.error( 3082 Messages.get().getBundle().key( 3083 Messages.LOG_WRITING_PUBLISHING_HISTORY_1, 3084 onlineResource.getRootPath()), 3085 e); 3086 } 3087 throw e; 3088 } 3089 return offlineResource.getState().isDeleted() 3090 ? CmsResource.STATE_DELETED 3091 : CmsPublishedResource.STATE_MOVED_DESTINATION; 3092 } 3093 3094 /** 3095 * Returns a SQL parameter string for the given data.<p> 3096 * 3097 * @param data the data 3098 * 3099 * @return the SQL parameter 3100 */ 3101 protected String getParameterString(Collection<?> data) { 3102 3103 StringBuffer conditions = new StringBuffer(); 3104 conditions.append(BEGIN_CONDITION); 3105 Iterator<?> it = data.iterator(); 3106 while (it.hasNext()) { 3107 it.next(); 3108 conditions.append("?"); 3109 if (it.hasNext()) { 3110 conditions.append(", "); 3111 } 3112 } 3113 conditions.append(END_CONDITION); 3114 return conditions.toString(); 3115 } 3116 3117 /** 3118 * Implementation of reading the user publish list which uses the log table.<p> 3119 * 3120 * This is the old implementation of the user publish list and can get pretty slow.<p> 3121 * 3122 * @param dbc the current database context 3123 * @param userId the id of the user for which we want the user publish list 3124 * 3125 * @return the publish list for the given user 3126 * 3127 * @throws CmsDataAccessException if something goes wrong 3128 */ 3129 protected List<CmsResource> getUsersPubListFromLog(CmsDbContext dbc, CmsUUID userId) throws CmsDataAccessException { 3130 3131 Connection conn = null; 3132 PreparedStatement stmt = null; 3133 ResultSet res = null; 3134 3135 List<CmsResource> result = null; 3136 try { 3137 conn = m_sqlManager.getConnection(dbc); 3138 stmt = m_sqlManager.getPreparedStatement(conn, dbc.currentProject().getUuid(), "C_LOG_READ_PUBLISH_LIST_2"); 3139 stmt.setString(1, userId.toString()); 3140 stmt.setString(2, userId.toString()); 3141 res = stmt.executeQuery(); 3142 3143 result = new ArrayList<CmsResource>(); 3144 while (res.next()) { 3145 CmsResource resource = m_driverManager.getVfsDriver(dbc).createResource( 3146 res, 3147 dbc.currentProject().getUuid()); 3148 long date = res.getLong(m_sqlManager.readQuery("C_LOG_DATE")); 3149 resource.setDateLastModified(date); 3150 result.add(resource); 3151 } 3152 } catch (SQLException e) { 3153 throw new CmsDbSqlException( 3154 Messages.get().container(Messages.ERR_GENERIC_SQL_1, CmsDbSqlException.getErrorQuery(stmt)), 3155 e); 3156 } finally { 3157 m_sqlManager.closeAll(dbc, conn, stmt, res); 3158 } 3159 return result; 3160 } 3161 3162 /** 3163 * Creates a new project from the current row of the given result set.<p> 3164 * 3165 * @param res the result set 3166 * 3167 * @return the new project 3168 * 3169 * @throws SQLException is something goes wrong 3170 */ 3171 protected CmsProject internalCreateProject(ResultSet res) throws SQLException { 3172 3173 String ou = CmsOrganizationalUnit.removeLeadingSeparator( 3174 res.getString(m_sqlManager.readQuery("C_PROJECTS_PROJECT_OU_0"))); 3175 return new CmsProject( 3176 new CmsUUID(res.getString(m_sqlManager.readQuery("C_PROJECTS_PROJECT_ID_0"))), 3177 ou + res.getString(m_sqlManager.readQuery("C_PROJECTS_PROJECT_NAME_0")), 3178 res.getString(m_sqlManager.readQuery("C_PROJECTS_PROJECT_DESCRIPTION_0")), 3179 new CmsUUID(res.getString(m_sqlManager.readQuery("C_PROJECTS_USER_ID_0"))), 3180 new CmsUUID(res.getString(m_sqlManager.readQuery("C_PROJECTS_GROUP_ID_0"))), 3181 new CmsUUID(res.getString(m_sqlManager.readQuery("C_PROJECTS_MANAGERGROUP_ID_0"))), 3182 res.getInt(m_sqlManager.readQuery("C_PROJECTS_PROJECT_FLAGS_0")), 3183 res.getLong(m_sqlManager.readQuery("C_PROJECTS_DATE_CREATED_0")), 3184 CmsProject.CmsProjectType.valueOf(res.getInt(m_sqlManager.readQuery("C_PROJECTS_PROJECT_TYPE_0")))); 3185 } 3186 3187 /** 3188 * Builds a publish list from serialized data.<p> 3189 * 3190 * @param bytes the byte array containing the serailized data for the publish list 3191 * @return the initialized publish list 3192 * 3193 * @throws IOException if deserialization fails 3194 * @throws ClassNotFoundException if deserialization fails 3195 */ 3196 protected CmsPublishList internalDeserializePublishList(byte[] bytes) throws IOException, ClassNotFoundException { 3197 3198 ByteArrayInputStream bin = new ByteArrayInputStream(bytes); 3199 ObjectInputStream oin = new ObjectInputStream(bin); 3200 return (CmsPublishList)oin.readObject(); 3201 } 3202 3203 /** 3204 * Creates a new {@link CmsLogEntry} object from the given result set entry.<p> 3205 * 3206 * @param res the result set 3207 * 3208 * @return the new {@link CmsLogEntry} object 3209 * 3210 * @throws SQLException if something goes wrong 3211 */ 3212 protected CmsLogEntry internalReadLogEntry(ResultSet res) throws SQLException { 3213 3214 CmsUUID userId = new CmsUUID(res.getString(m_sqlManager.readQuery("C_LOG_USER_ID"))); 3215 long date = res.getLong(m_sqlManager.readQuery("C_LOG_DATE")); 3216 CmsUUID structureId = new CmsUUID(res.getString(m_sqlManager.readQuery("C_LOG_STRUCTURE_ID"))); 3217 CmsLogEntryType type = CmsLogEntryType.valueOf(res.getInt(m_sqlManager.readQuery("C_LOG_TYPE"))); 3218 String[] data = CmsStringUtil.splitAsArray(res.getString(m_sqlManager.readQuery("C_LOG_DATA")), '|'); 3219 return new CmsLogEntry(userId, date, structureId, type, data); 3220 } 3221 3222 /** 3223 * Resets the state to UNCHANGED for a specified resource.<p> 3224 * 3225 * @param dbc the current database context 3226 * @param resource the Cms resource 3227 * 3228 * @throws CmsDataAccessException if something goes wrong 3229 */ 3230 protected void internalResetResourceState(CmsDbContext dbc, CmsResource resource) throws CmsDataAccessException { 3231 3232 try { 3233 // reset the resource state 3234 resource.setState(CmsResource.STATE_UNCHANGED); 3235 m_driverManager.getVfsDriver( 3236 dbc).writeResourceState(dbc, dbc.currentProject(), resource, CmsDriverManager.UPDATE_ALL, true); 3237 } catch (CmsDataAccessException e) { 3238 if (LOG.isErrorEnabled()) { 3239 LOG.error( 3240 Messages.get().getBundle().key( 3241 Messages.LOG_ERROR_RESETTING_RESOURCE_STATE_1, 3242 resource.getRootPath()), 3243 e); 3244 } 3245 throw e; 3246 } 3247 } 3248 3249 /** 3250 * Serialize publish list to write it as byte array to the database.<p> 3251 * 3252 * @param publishList the publish list 3253 * @return byte array containing the publish list data 3254 * @throws IOException if something goes wrong 3255 */ 3256 protected byte[] internalSerializePublishList(CmsPublishList publishList) throws IOException { 3257 3258 // serialize the publish list 3259 ByteArrayOutputStream bout = new ByteArrayOutputStream(); 3260 ObjectOutputStream oout = new ObjectOutputStream(bout); 3261 oout.writeObject(publishList); 3262 oout.close(); 3263 return bout.toByteArray(); 3264 } 3265 3266 /** 3267 * Writes the needed history entries.<p> 3268 * 3269 * @param dbc the current database context 3270 * @param resource the offline resource 3271 * @param publishHistoryResource the resource to use for the publish history (if null, uses the value of resource instead) 3272 * @param state the state to store in the publish history entry 3273 * @param properties the offline properties 3274 * @param publishHistoryId the current publish process id 3275 * @param publishTag the current publish process tag 3276 * 3277 * @throws CmsDataAccessException if something goes wrong 3278 */ 3279 protected void internalWriteHistory( 3280 CmsDbContext dbc, 3281 CmsResource resource, 3282 CmsResource publishHistoryResource, 3283 CmsResourceState state, 3284 List<CmsProperty> properties, 3285 CmsUUID publishHistoryId, 3286 int publishTag) 3287 throws CmsDataAccessException { 3288 3289 try { 3290 if (OpenCms.getSystemInfo().isHistoryEnabled()) { 3291 // write the resource to the historical archive 3292 if (properties == null) { 3293 properties = m_driverManager.getVfsDriver(dbc).readPropertyObjects( 3294 dbc, 3295 dbc.currentProject(), 3296 resource); 3297 } 3298 m_driverManager.getHistoryDriver(dbc).writeResource(dbc, resource, properties, publishTag); 3299 } 3300 // write the resource to the publish history 3301 m_driverManager.getProjectDriver(dbc).writePublishHistory( 3302 dbc, 3303 publishHistoryId, 3304 new CmsPublishedResource( 3305 publishHistoryResource != null ? publishHistoryResource : resource, 3306 publishTag, 3307 state)); 3308 } catch (CmsDataAccessException e) { 3309 if (LOG.isErrorEnabled()) { 3310 LOG.error( 3311 Messages.get().getBundle().key(Messages.LOG_WRITING_PUBLISHING_HISTORY_1, resource.getRootPath()), 3312 e); 3313 } 3314 throw e; 3315 } 3316 } 3317 3318 /** 3319 * Build the whole WHERE SQL statement part for the given log entry filter.<p> 3320 * 3321 * @param filter the filter 3322 * 3323 * @return a pair containing both the SQL and the parameters for it 3324 */ 3325 protected CmsPair<String, List<I_CmsPreparedStatementParameter>> prepareLogConditions(CmsLogFilter filter) { 3326 3327 List<I_CmsPreparedStatementParameter> params = new ArrayList<I_CmsPreparedStatementParameter>(); 3328 StringBuffer conditions = new StringBuffer(); 3329 3330 // user id filter 3331 if (filter.getUserId() != null) { 3332 if (conditions.length() == 0) { 3333 conditions.append(BEGIN_CONDITION); 3334 } else { 3335 conditions.append(BEGIN_INCLUDE_CONDITION); 3336 } 3337 conditions.append(m_sqlManager.readQuery("C_LOG_FILTER_USER_ID")); 3338 params.add(new CmsPreparedStatementStringParameter(filter.getUserId().toString())); 3339 conditions.append(END_CONDITION); 3340 } 3341 3342 // resource id filter 3343 if (filter.getStructureId() != null) { 3344 if (conditions.length() == 0) { 3345 conditions.append(BEGIN_CONDITION); 3346 } else { 3347 conditions.append(BEGIN_INCLUDE_CONDITION); 3348 } 3349 conditions.append(m_sqlManager.readQuery("C_LOG_FILTER_RESOURCE_ID")); 3350 params.add(new CmsPreparedStatementStringParameter(filter.getStructureId().toString())); 3351 conditions.append(END_CONDITION); 3352 } 3353 3354 // date from filter 3355 if (filter.getDateFrom() != CmsResource.DATE_RELEASED_DEFAULT) { 3356 if (conditions.length() == 0) { 3357 conditions.append(BEGIN_CONDITION); 3358 } else { 3359 conditions.append(BEGIN_INCLUDE_CONDITION); 3360 } 3361 conditions.append(m_sqlManager.readQuery("C_LOG_FILTER_DATE_FROM")); 3362 params.add(new CmsPreparedStatementLongParameter(filter.getDateFrom())); 3363 conditions.append(END_CONDITION); 3364 } 3365 3366 // date to filter 3367 if (filter.getDateTo() != CmsResource.DATE_RELEASED_DEFAULT) { 3368 if (conditions.length() == 0) { 3369 conditions.append(BEGIN_CONDITION); 3370 } else { 3371 conditions.append(BEGIN_INCLUDE_CONDITION); 3372 } 3373 conditions.append(m_sqlManager.readQuery("C_LOG_FILTER_DATE_TO")); 3374 params.add(new CmsPreparedStatementLongParameter(filter.getDateTo())); 3375 conditions.append(END_CONDITION); 3376 } 3377 3378 // include type filter 3379 Set<CmsLogEntryType> includeTypes = filter.getIncludeTypes(); 3380 if (!includeTypes.isEmpty()) { 3381 if (conditions.length() == 0) { 3382 conditions.append(BEGIN_CONDITION); 3383 } else { 3384 conditions.append(BEGIN_INCLUDE_CONDITION); 3385 } 3386 conditions.append(m_sqlManager.readQuery("C_LOG_FILTER_INCLUDE_TYPE")); 3387 conditions.append(BEGIN_CONDITION); 3388 Iterator<CmsLogEntryType> it = includeTypes.iterator(); 3389 while (it.hasNext()) { 3390 CmsLogEntryType type = it.next(); 3391 conditions.append("?"); 3392 params.add(new CmsPreparedStatementIntParameter(type.getId())); 3393 if (it.hasNext()) { 3394 conditions.append(", "); 3395 } 3396 } 3397 conditions.append(END_CONDITION); 3398 conditions.append(END_CONDITION); 3399 } 3400 3401 // exclude type filter 3402 Set<CmsLogEntryType> excludeTypes = filter.getExcludeTypes(); 3403 if (!excludeTypes.isEmpty()) { 3404 if (conditions.length() == 0) { 3405 conditions.append(BEGIN_CONDITION); 3406 } else { 3407 conditions.append(BEGIN_INCLUDE_CONDITION); 3408 } 3409 conditions.append(m_sqlManager.readQuery("C_LOG_FILTER_EXCLUDE_TYPE")); 3410 conditions.append(BEGIN_CONDITION); 3411 Iterator<CmsLogEntryType> it = excludeTypes.iterator(); 3412 while (it.hasNext()) { 3413 CmsLogEntryType type = it.next(); 3414 conditions.append("?"); 3415 params.add(new CmsPreparedStatementIntParameter(type.getId())); 3416 if (it.hasNext()) { 3417 conditions.append(", "); 3418 } 3419 } 3420 conditions.append(END_CONDITION); 3421 conditions.append(END_CONDITION); 3422 } 3423 return CmsPair.create(conditions.toString(), params); 3424 } 3425 3426 /** 3427 * Publishes a changed file.<p> 3428 * 3429 * @param dbc the current database context 3430 * @param onlineProject the online project 3431 * @param offlineResource the resource to publish 3432 * @param publishedResourceIds contains the UUIDs of already published content records 3433 * @param publishHistoryId the publish history id 3434 * @param publishTag the publish tag 3435 * 3436 * @throws CmsDataAccessException is something goes wrong 3437 */ 3438 protected void publishChangedFile( 3439 CmsDbContext dbc, 3440 CmsProject onlineProject, 3441 CmsResource offlineResource, 3442 Set<CmsUUID> publishedResourceIds, 3443 CmsUUID publishHistoryId, 3444 int publishTag) 3445 throws CmsDataAccessException { 3446 3447 CmsResource onlineResource = null; 3448 boolean needToUpdateContent = true; 3449 boolean existsOnline = m_driverManager.getVfsDriver(dbc).validateStructureIdExists( 3450 dbc, 3451 CmsProject.ONLINE_PROJECT_ID, 3452 offlineResource.getStructureId()); 3453 CmsResourceState resourceState = existsOnline 3454 ? fixMovedResource(dbc, onlineProject, offlineResource, publishHistoryId, publishTag) 3455 : offlineResource.getState(); 3456 try { 3457 // reset the labeled link flag before writing the online file 3458 int flags = offlineResource.getFlags(); 3459 flags &= ~CmsResource.FLAG_LABELED; 3460 offlineResource.setFlags(flags); 3461 3462 if (existsOnline) { 3463 // read the file header online 3464 onlineResource = m_driverManager.getVfsDriver( 3465 dbc).readResource(dbc, onlineProject.getUuid(), offlineResource.getStructureId(), false); 3466 needToUpdateContent = (onlineResource.getDateContent() < offlineResource.getDateContent()); 3467 // delete the properties online 3468 m_driverManager.getVfsDriver(dbc).deletePropertyObjects( 3469 dbc, 3470 onlineProject.getUuid(), 3471 onlineResource, 3472 CmsProperty.DELETE_OPTION_DELETE_STRUCTURE_AND_RESOURCE_VALUES); 3473 3474 // if the offline file has a resource ID different from the online file 3475 // (probably because a deleted file was replaced by a new file with the 3476 // same name), the properties mapped to the "old" resource ID have to be 3477 // deleted also offline. if this is the case, the online and offline structure 3478 // ID's do match, but the resource ID's are different. structure IDs are reused 3479 // to prevent orphan structure records in the online project. 3480 3481 // Addendum (2023): It shouldn't be possible for resources to be in this state anymore, 3482 // since creating new resources over deleted ones isn't really possible anymore, 3483 // but apparently it can still happen, though I can't reproduce it. 3484 if (!onlineResource.getResourceId().equals(offlineResource.getResourceId())) { 3485 List<CmsProperty> offlineProperties = m_driverManager.getVfsDriver(dbc).readPropertyObjects( 3486 dbc, 3487 dbc.currentProject(), 3488 onlineResource); 3489 if (offlineProperties.size() > 0) { 3490 List<CmsProperty> newProperties = new ArrayList<>(); 3491 for (int i = 0; i < offlineProperties.size(); i++) { 3492 CmsProperty oldProperty = offlineProperties.get(i); 3493 // property may be frozen (non-modifiable), so create a new one 3494 CmsProperty newProperty = new CmsProperty( 3495 oldProperty.getName(), 3496 null, 3497 CmsProperty.DELETE_VALUE); 3498 newProperties.add(newProperty); 3499 } 3500 m_driverManager.getVfsDriver( 3501 dbc).writePropertyObjects(dbc, dbc.currentProject(), onlineResource, newProperties); 3502 } 3503 } 3504 } 3505 } catch (CmsDataAccessException e) { 3506 if (LOG.isErrorEnabled()) { 3507 LOG.error( 3508 Messages.get().getBundle().key(Messages.LOG_DELETING_PROPERTIES_1, offlineResource.toString()), 3509 e); 3510 } 3511 throw e; 3512 } 3513 3514 CmsFile newFile; 3515 try { 3516 // publish the file content 3517 newFile = m_driverManager.getProjectDriver(dbc).publishFileContent( 3518 dbc, 3519 dbc.currentProject(), 3520 onlineProject, 3521 offlineResource, 3522 publishedResourceIds, 3523 needToUpdateContent, 3524 publishTag); 3525 3526 } catch (CmsDataAccessException e) { 3527 if (LOG.isErrorEnabled()) { 3528 LOG.error( 3529 Messages.get().getBundle().key(Messages.LOG_PUBLISHING_RESOURCE_1, offlineResource.getRootPath()), 3530 e); 3531 } 3532 throw e; 3533 } 3534 3535 List<CmsProperty> offlineProperties; 3536 try { 3537 // write the properties online 3538 offlineProperties = m_driverManager.getVfsDriver(dbc).readPropertyObjects( 3539 dbc, 3540 dbc.currentProject(), 3541 offlineResource); 3542 CmsProperty.setAutoCreatePropertyDefinitions(offlineProperties, true); 3543 m_driverManager.getVfsDriver(dbc).writePropertyObjects(dbc, onlineProject, newFile, offlineProperties); 3544 } catch (CmsDataAccessException e) { 3545 if (LOG.isErrorEnabled()) { 3546 LOG.error( 3547 Messages.get().getBundle().key(Messages.LOG_PUBLISHING_PROPERTIES_1, newFile.getRootPath()), 3548 e); 3549 } 3550 throw e; 3551 } 3552 3553 try { 3554 // write the ACL online 3555 m_driverManager.getUserDriver(dbc).publishAccessControlEntries( 3556 dbc, 3557 dbc.currentProject(), 3558 onlineProject, 3559 newFile.getResourceId(), 3560 offlineResource.getResourceId()); 3561 } catch (CmsDataAccessException e) { 3562 if (LOG.isErrorEnabled()) { 3563 LOG.error(Messages.get().getBundle().key(Messages.LOG_PUBLISHING_ACL_1, newFile.getRootPath()), e); 3564 } 3565 throw e; 3566 } 3567 3568 CmsFile offlineFile = new CmsFile(offlineResource); 3569 offlineFile.setContents(newFile.getContents()); 3570 internalWriteHistory(dbc, offlineFile, null, resourceState, offlineProperties, publishHistoryId, publishTag); 3571 3572 m_driverManager.getVfsDriver(dbc).updateRelations(dbc, onlineProject, offlineResource); 3573 } 3574 3575 /** 3576 * Publishes a deleted file.<p> 3577 * 3578 * @param dbc the current database context 3579 * @param onlineProject the online project 3580 * @param offlineResource the resource to publish 3581 * @param publishHistoryId the publish history id 3582 * @param publishTag the publish tag 3583 * 3584 * @throws CmsDataAccessException is something goes wrong 3585 */ 3586 protected void publishDeletedFile( 3587 CmsDbContext dbc, 3588 CmsProject onlineProject, 3589 CmsResource offlineResource, 3590 CmsUUID publishHistoryId, 3591 int publishTag) 3592 throws CmsDataAccessException { 3593 3594 CmsResourceState resourceState = fixMovedResource( 3595 dbc, 3596 onlineProject, 3597 offlineResource, 3598 publishHistoryId, 3599 publishTag); 3600 3601 boolean existsOnline = m_driverManager.getVfsDriver(dbc).validateStructureIdExists( 3602 dbc, 3603 CmsProject.ONLINE_PROJECT_ID, 3604 offlineResource.getStructureId()); 3605 CmsResource onlineResource = null; 3606 if (existsOnline) { 3607 try { 3608 // read the file header online 3609 onlineResource = m_driverManager.getVfsDriver( 3610 dbc).readResource(dbc, onlineProject.getUuid(), offlineResource.getStructureId(), true); 3611 } catch (CmsDataAccessException e) { 3612 if (LOG.isErrorEnabled()) { 3613 LOG.error( 3614 Messages.get().getBundle().key(Messages.LOG_READING_RESOURCE_1, offlineResource.getRootPath()), 3615 e); 3616 } 3617 throw e; 3618 } 3619 } 3620 if (offlineResource.isLabeled() && !m_driverManager.labelResource(dbc, offlineResource, null, 2)) { 3621 // update the resource flags to "unlabeled" of the siblings of the offline resource 3622 int flags = offlineResource.getFlags(); 3623 flags &= ~CmsResource.FLAG_LABELED; 3624 offlineResource.setFlags(flags); 3625 } 3626 3627 // write history before deleting 3628 CmsFile offlineFile = new CmsFile(offlineResource); 3629 offlineFile.setContents( 3630 m_driverManager.getVfsDriver(dbc).readContent( 3631 dbc, 3632 dbc.currentProject().getUuid(), 3633 offlineFile.getResourceId())); 3634 internalWriteHistory(dbc, offlineFile, null, resourceState, null, publishHistoryId, publishTag); 3635 3636 int propertyDeleteOption = -1; 3637 try { 3638 // delete the properties online and offline 3639 if (offlineResource.getSiblingCount() > 1) { 3640 // there are other siblings- delete only structure property values and keep the resource property values 3641 propertyDeleteOption = CmsProperty.DELETE_OPTION_DELETE_STRUCTURE_VALUES; 3642 } else { 3643 // there are no other siblings- delete both the structure and resource property values 3644 propertyDeleteOption = CmsProperty.DELETE_OPTION_DELETE_STRUCTURE_AND_RESOURCE_VALUES; 3645 } 3646 3647 if (existsOnline) { 3648 m_driverManager.getVfsDriver( 3649 dbc).deletePropertyObjects(dbc, onlineProject.getUuid(), onlineResource, propertyDeleteOption); 3650 } 3651 m_driverManager.getVfsDriver( 3652 dbc).deletePropertyObjects(dbc, dbc.currentProject().getUuid(), offlineResource, propertyDeleteOption); 3653 3654 // if the offline file has a resource ID different from the online file 3655 // (probably because a (deleted) file was replaced by a new file with the 3656 // same name), the properties with the "old" resource ID have to be 3657 // deleted also offline 3658 if (existsOnline 3659 && (onlineResource != null) 3660 && !onlineResource.getResourceId().equals(offlineResource.getResourceId())) { 3661 m_driverManager.getVfsDriver(dbc).deletePropertyObjects( 3662 dbc, 3663 dbc.currentProject().getUuid(), 3664 onlineResource, 3665 CmsProperty.DELETE_OPTION_DELETE_STRUCTURE_AND_RESOURCE_VALUES); 3666 } 3667 } catch (CmsDataAccessException e) { 3668 if (LOG.isErrorEnabled()) { 3669 LOG.error( 3670 Messages.get().getBundle().key(Messages.LOG_DELETING_PROPERTIES_1, offlineResource.getRootPath()), 3671 e); 3672 } 3673 throw e; 3674 } 3675 3676 try { 3677 // remove the file online and offline 3678 m_driverManager.getVfsDriver(dbc).removeFile(dbc, dbc.currentProject().getUuid(), offlineResource); 3679 if (existsOnline && (onlineResource != null)) { 3680 m_driverManager.getVfsDriver(dbc).removeFile(dbc, onlineProject.getUuid(), onlineResource); 3681 } 3682 } catch (CmsDataAccessException e) { 3683 if (LOG.isErrorEnabled()) { 3684 LOG.error( 3685 Messages.get().getBundle().key(Messages.LOG_REMOVING_RESOURCE_1, offlineResource.getRootPath()), 3686 e); 3687 } 3688 throw e; 3689 } 3690 3691 // delete the ACL online and offline 3692 try { 3693 if (existsOnline && (onlineResource != null) && (onlineResource.getSiblingCount() == 1)) { 3694 // only if no siblings left 3695 m_driverManager.getUserDriver(dbc).removeAccessControlEntries( 3696 dbc, 3697 onlineProject, 3698 onlineResource.getResourceId()); 3699 } 3700 if (offlineResource.getSiblingCount() == 1) { 3701 // only if no siblings left 3702 m_driverManager.getUserDriver(dbc).removeAccessControlEntries( 3703 dbc, 3704 dbc.currentProject(), 3705 offlineResource.getResourceId()); 3706 } 3707 } catch (CmsDataAccessException e) { 3708 if (LOG.isErrorEnabled()) { 3709 LOG.error(Messages.get().getBundle().key(Messages.LOG_REMOVING_ACL_1, offlineResource.toString()), e); 3710 } 3711 throw e; 3712 } 3713 3714 try { 3715 // delete relations online and offline 3716 m_driverManager.getVfsDriver( 3717 dbc).deleteRelations(dbc, onlineProject.getUuid(), offlineResource, CmsRelationFilter.TARGETS); 3718 m_driverManager.getVfsDriver( 3719 dbc).deleteRelations(dbc, dbc.currentProject().getUuid(), offlineResource, CmsRelationFilter.TARGETS); 3720 } catch (CmsDataAccessException e) { 3721 if (LOG.isErrorEnabled()) { 3722 LOG.error( 3723 Messages.get().getBundle().key(Messages.LOG_REMOVING_RELATIONS_1, offlineResource.toString()), 3724 e); 3725 } 3726 throw e; 3727 } 3728 3729 if (OpenCms.getSubscriptionManager().isEnabled()) { 3730 try { 3731 // delete visited information for resource from log 3732 CmsVisitEntryFilter filter = CmsVisitEntryFilter.ALL.filterResource(offlineResource.getStructureId()); 3733 m_driverManager.getSubscriptionDriver().deleteVisits( 3734 dbc, 3735 OpenCms.getSubscriptionManager().getPoolName(), 3736 filter); 3737 } catch (CmsDataAccessException e) { 3738 if (LOG.isErrorEnabled()) { 3739 LOG.error( 3740 Messages.get().getBundle().key(Messages.LOG_REMOVING_VISITEDLOG_1, offlineResource.toString()), 3741 e); 3742 } 3743 throw e; 3744 } 3745 3746 try { 3747 // mark the subscribed resource as deleted 3748 /* changed to subscription driver */ 3749 // m_driverManager.getUserDriver(dbc).setSubscribedResourceAsDeleted( 3750 // dbc, 3751 // OpenCms.getSubscriptionManager().getPoolName(), 3752 // offlineResource); 3753 m_driverManager.getSubscriptionDriver().setSubscribedResourceAsDeleted( 3754 dbc, 3755 OpenCms.getSubscriptionManager().getPoolName(), 3756 offlineResource); 3757 } catch (CmsDataAccessException e) { 3758 if (LOG.isErrorEnabled()) { 3759 LOG.error( 3760 Messages.get().getBundle().key( 3761 Messages.LOG_REMOVING_SUBSCRIPTIONS_1, 3762 offlineResource.toString()), 3763 e); 3764 } 3765 throw e; 3766 } 3767 } 3768 } 3769 3770 /** 3771 * Publishes a new file.<p> 3772 * 3773 * @param dbc the current database context 3774 * @param onlineProject the online project 3775 * @param offlineResource the resource to publish 3776 * @param publishedContentIds contains the UUIDs of already published content records 3777 * @param publishHistoryId the publish history id 3778 * @param publishTag the publish tag 3779 * 3780 * @throws CmsDataAccessException is something goes wrong 3781 */ 3782 protected void publishNewFile( 3783 CmsDbContext dbc, 3784 CmsProject onlineProject, 3785 CmsResource offlineResource, 3786 Set<CmsUUID> publishedContentIds, 3787 CmsUUID publishHistoryId, 3788 int publishTag) 3789 throws CmsDataAccessException { 3790 3791 CmsResourceState resourceState = fixMovedResource( 3792 dbc, 3793 onlineProject, 3794 offlineResource, 3795 publishHistoryId, 3796 publishTag); 3797 3798 CmsFile newFile; 3799 try { 3800 // reset the labeled link flag before writing the online file 3801 int flags = offlineResource.getFlags(); 3802 flags &= ~CmsResource.FLAG_LABELED; 3803 offlineResource.setFlags(flags); 3804 3805 // publish the file content 3806 newFile = m_driverManager.getProjectDriver(dbc).publishFileContent( 3807 dbc, 3808 dbc.currentProject(), 3809 onlineProject, 3810 offlineResource, 3811 publishedContentIds, 3812 true, 3813 publishTag); 3814 3815 } catch (CmsVfsResourceAlreadyExistsException e) { 3816 try { 3817 // remove the existing file and ensure that it's content is written 3818 // in any case by removing it's resource ID from the set of published resource IDs 3819 m_driverManager.getVfsDriver(dbc).removeFile(dbc, onlineProject.getUuid(), offlineResource); 3820 publishedContentIds.remove(offlineResource.getResourceId()); 3821 newFile = m_driverManager.getProjectDriver(dbc).publishFileContent( 3822 dbc, 3823 dbc.currentProject(), 3824 onlineProject, 3825 offlineResource, 3826 publishedContentIds, 3827 true, 3828 publishTag); 3829 3830 } catch (CmsDataAccessException e1) { 3831 if (LOG.isErrorEnabled()) { 3832 LOG.error( 3833 Messages.get().getBundle().key( 3834 Messages.LOG_PUBLISHING_RESOURCE_1, 3835 offlineResource.getRootPath()), 3836 e); 3837 } 3838 throw e1; 3839 } 3840 } catch (CmsDataAccessException e) { 3841 if (LOG.isErrorEnabled()) { 3842 LOG.error( 3843 Messages.get().getBundle().key(Messages.LOG_PUBLISHING_RESOURCE_1, offlineResource.getRootPath()), 3844 e); 3845 } 3846 throw e; 3847 } 3848 3849 List<CmsProperty> offlineProperties; 3850 try { 3851 // write the properties online 3852 offlineProperties = m_driverManager.getVfsDriver(dbc).readPropertyObjects( 3853 dbc, 3854 dbc.currentProject(), 3855 offlineResource); 3856 CmsProperty.setAutoCreatePropertyDefinitions(offlineProperties, true); 3857 m_driverManager.getVfsDriver(dbc).writePropertyObjects(dbc, onlineProject, newFile, offlineProperties); 3858 } catch (CmsDataAccessException e) { 3859 if (LOG.isErrorEnabled()) { 3860 LOG.error( 3861 Messages.get().getBundle().key(Messages.LOG_PUBLISHING_PROPERTIES_1, newFile.getRootPath()), 3862 e); 3863 } 3864 3865 throw e; 3866 } 3867 3868 try { 3869 // write the ACL online 3870 m_driverManager.getUserDriver(dbc).publishAccessControlEntries( 3871 dbc, 3872 dbc.currentProject(), 3873 onlineProject, 3874 offlineResource.getResourceId(), 3875 newFile.getResourceId()); 3876 } catch (CmsDataAccessException e) { 3877 if (LOG.isErrorEnabled()) { 3878 LOG.error(Messages.get().getBundle().key(Messages.LOG_PUBLISHING_ACL_1, newFile.getRootPath()), e); 3879 } 3880 throw e; 3881 } 3882 3883 CmsFile offlineFile = new CmsFile(offlineResource); 3884 offlineFile.setContents(newFile.getContents()); 3885 internalWriteHistory(dbc, offlineFile, null, resourceState, offlineProperties, publishHistoryId, publishTag); 3886 3887 m_driverManager.getVfsDriver(dbc).updateRelations(dbc, onlineProject, offlineResource); 3888 } 3889 3890}