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