001/* 002 * (C) Copyright 2006-2009 Nuxeo SA (http://nuxeo.com/) and others. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 * 016 * Contributors: 017 * Nuxeo 018 */ 019 020package org.nuxeo.ecm.platform.publisher.impl.service; 021 022import java.util.ArrayList; 023import java.util.HashMap; 024import java.util.Iterator; 025import java.util.List; 026import java.util.Map; 027 028import org.apache.commons.logging.Log; 029import org.apache.commons.logging.LogFactory; 030import org.nuxeo.common.utils.Path; 031import org.nuxeo.ecm.core.api.CoreInstance; 032import org.nuxeo.ecm.core.api.CoreSession; 033import org.nuxeo.ecm.core.api.DocumentLocation; 034import org.nuxeo.ecm.core.api.DocumentModel; 035import org.nuxeo.ecm.core.api.NuxeoException; 036import org.nuxeo.ecm.core.api.repository.RepositoryManager; 037import org.nuxeo.ecm.core.repository.RepositoryService; 038import org.nuxeo.ecm.platform.publisher.api.PublicationNode; 039import org.nuxeo.ecm.platform.publisher.api.PublicationTree; 040import org.nuxeo.ecm.platform.publisher.api.PublicationTreeNotAvailable; 041import org.nuxeo.ecm.platform.publisher.api.PublishedDocument; 042import org.nuxeo.ecm.platform.publisher.api.PublishedDocumentFactory; 043import org.nuxeo.ecm.platform.publisher.api.PublisherService; 044import org.nuxeo.ecm.platform.publisher.api.RemotePublicationTreeManager; 045import org.nuxeo.ecm.platform.publisher.descriptors.PublicationTreeConfigDescriptor; 046import org.nuxeo.ecm.platform.publisher.descriptors.PublicationTreeDescriptor; 047import org.nuxeo.ecm.platform.publisher.descriptors.PublishedDocumentFactoryDescriptor; 048import org.nuxeo.ecm.platform.publisher.descriptors.RootSectionFinderFactoryDescriptor; 049import org.nuxeo.ecm.platform.publisher.helper.PublicationRelationHelper; 050import org.nuxeo.ecm.platform.publisher.helper.RootSectionFinder; 051import org.nuxeo.ecm.platform.publisher.helper.RootSectionFinderFactory; 052import org.nuxeo.ecm.platform.publisher.impl.finder.DefaultRootSectionsFinder; 053import org.nuxeo.ecm.platform.publisher.rules.ValidatorsRule; 054import org.nuxeo.ecm.platform.publisher.rules.ValidatorsRuleDescriptor; 055import org.nuxeo.runtime.api.Framework; 056import org.nuxeo.runtime.model.ComponentContext; 057import org.nuxeo.runtime.model.ComponentInstance; 058import org.nuxeo.runtime.model.DefaultComponent; 059import org.nuxeo.runtime.transaction.TransactionHelper; 060 061/** 062 * POJO implementation of the publisher service Implements both {@link PublisherService} and 063 * {@link RemotePublicationTreeManager}. 064 * 065 * @author tiry 066 */ 067public class PublisherServiceImpl extends DefaultComponent implements PublisherService, RemotePublicationTreeManager { 068 069 private final Log log = LogFactory.getLog(PublisherServiceImpl.class); 070 071 protected Map<String, PublicationTreeDescriptor> treeDescriptors = new HashMap<String, PublicationTreeDescriptor>(); 072 073 protected Map<String, PublishedDocumentFactoryDescriptor> factoryDescriptors = new HashMap<String, PublishedDocumentFactoryDescriptor>(); 074 075 protected Map<String, PublicationTreeConfigDescriptor> treeConfigDescriptors = new HashMap<String, PublicationTreeConfigDescriptor>(); 076 077 protected Map<String, ValidatorsRuleDescriptor> validatorsRuleDescriptors = new HashMap<String, ValidatorsRuleDescriptor>(); 078 079 protected Map<String, PublicationTreeConfigDescriptor> pendingDescriptors = new HashMap<String, PublicationTreeConfigDescriptor>(); 080 081 protected Map<String, PublicationTree> liveTrees = new HashMap<String, PublicationTree>(); 082 083 protected RootSectionFinderFactory rootSectionFinderFactory = null; 084 085 // Store association between treeSid and CoreSession that was opened locally 086 // for them : this unable proper cleanup of allocated sessions 087 protected Map<String, String> remoteLiveTrees = new HashMap<String, String>(); 088 089 public static final String TREE_EP = "tree"; 090 091 public static final String TREE_CONFIG_EP = "treeInstance"; 092 093 public static final String VALIDATORS_RULE_EP = "validatorsRule"; 094 095 public static final String FACTORY_EP = "factory"; 096 097 public static final String ROOT_SECTION_FINDER_FACTORY_EP = "rootSectionFinderFactory"; 098 099 protected static final String ROOT_PATH_KEY = "RootPath"; 100 101 protected static final String RELATIVE_ROOT_PATH_KEY = "RelativeRootPath"; 102 103 @Override 104 public void applicationStarted(ComponentContext context) { 105 RepositoryService repositoryService = Framework.getService(RepositoryService.class); 106 if (repositoryService == null) { 107 // RepositoryService failed to start, no need to go further 108 return; 109 } 110 boolean txWasStartedOutsideComponent = TransactionHelper.isTransactionActiveOrMarkedRollback(); 111 112 if (txWasStartedOutsideComponent || TransactionHelper.startTransaction()) { 113 boolean completedAbruptly = true; 114 try { 115 doApplicationStarted(); 116 completedAbruptly = false; 117 } finally { 118 if (completedAbruptly) { 119 TransactionHelper.setTransactionRollbackOnly(); 120 } 121 if (!txWasStartedOutsideComponent) { 122 TransactionHelper.commitOrRollbackTransaction(); 123 } 124 } 125 } else { 126 doApplicationStarted(); 127 } 128 } 129 130 protected void doApplicationStarted() { 131 ClassLoader jbossCL = Thread.currentThread().getContextClassLoader(); 132 ClassLoader nuxeoCL = PublisherServiceImpl.class.getClassLoader(); 133 try { 134 Thread.currentThread().setContextClassLoader(nuxeoCL); 135 log.info("Publisher Service initialization"); 136 registerPendingDescriptors(); 137 } finally { 138 Thread.currentThread().setContextClassLoader(jbossCL); 139 log.debug("JBoss ClassLoader restored"); 140 } 141 } 142 143 @Override 144 public void activate(ComponentContext context) { 145 liveTrees = new HashMap<String, PublicationTree>(); 146 treeDescriptors = new HashMap<String, PublicationTreeDescriptor>(); 147 factoryDescriptors = new HashMap<String, PublishedDocumentFactoryDescriptor>(); 148 treeConfigDescriptors = new HashMap<String, PublicationTreeConfigDescriptor>(); 149 validatorsRuleDescriptors = new HashMap<String, ValidatorsRuleDescriptor>(); 150 pendingDescriptors = new HashMap<String, PublicationTreeConfigDescriptor>(); 151 } 152 153 // for testing cleanup 154 public int getLiveTreeCount() { 155 return liveTrees.size(); 156 } 157 158 public PublicationTree getTreeBySid(String sid) { 159 return liveTrees.get(sid); 160 } 161 162 @Override 163 public void registerContribution(Object contribution, String extensionPoint, ComponentInstance contributor) { 164 165 log.debug("Registry contribution for EP " + extensionPoint); 166 167 if (TREE_EP.equals(extensionPoint)) { 168 PublicationTreeDescriptor desc = (PublicationTreeDescriptor) contribution; 169 treeDescriptors.put(desc.getName(), desc); 170 } else if (TREE_CONFIG_EP.equals(extensionPoint)) { 171 PublicationTreeConfigDescriptor desc = (PublicationTreeConfigDescriptor) contribution; 172 registerTreeConfig(desc); 173 } else if (FACTORY_EP.equals(extensionPoint)) { 174 PublishedDocumentFactoryDescriptor desc = (PublishedDocumentFactoryDescriptor) contribution; 175 factoryDescriptors.put(desc.getName(), desc); 176 } else if (VALIDATORS_RULE_EP.equals(extensionPoint)) { 177 ValidatorsRuleDescriptor desc = (ValidatorsRuleDescriptor) contribution; 178 validatorsRuleDescriptors.put(desc.getName(), desc); 179 } else if (ROOT_SECTION_FINDER_FACTORY_EP.equals(extensionPoint)) { 180 RootSectionFinderFactoryDescriptor desc = (RootSectionFinderFactoryDescriptor) contribution; 181 try { 182 rootSectionFinderFactory = desc.getFactory().newInstance(); 183 } catch (ReflectiveOperationException t) { 184 log.error("Unable to load custom RootSectionFinderFactory", t); 185 } 186 } 187 } 188 189 protected void registerTreeConfig(PublicationTreeConfigDescriptor desc) { 190 if (desc.getParameters().get("RelativeRootPath") != null) { 191 pendingDescriptors.put(desc.getName(), desc); 192 } else { 193 treeConfigDescriptors.put(desc.getName(), desc); 194 } 195 } 196 197 @Override 198 public void unregisterContribution(Object contribution, String extensionPoint, ComponentInstance contributor) { 199 if (contribution instanceof PublicationTreeDescriptor) { 200 treeDescriptors.remove(((PublicationTreeDescriptor) contribution).getName()); 201 } else if (contribution instanceof PublicationTreeConfigDescriptor) { 202 String name = ((PublicationTreeConfigDescriptor) contribution).getName(); 203 pendingDescriptors.remove(name); 204 treeConfigDescriptors.remove(name); 205 } else if (contribution instanceof ValidatorsRuleDescriptor) { 206 validatorsRuleDescriptors.remove(((ValidatorsRuleDescriptor) contribution).getName()); 207 } else if (contribution instanceof RootSectionFinderFactoryDescriptor) { 208 rootSectionFinderFactory = null; 209 } 210 } 211 212 protected String computeTreeSessionId(String treeConfigName, CoreSession coreSession) { 213 return computeTreeSessionId(treeConfigName, coreSession.getSessionId()); 214 } 215 216 protected String computeTreeSessionId(String treeConfigName, String sid) { 217 return treeConfigName + sid; 218 } 219 220 @Override 221 public List<String> getAvailablePublicationTree() { 222 List<String> treeConfigs = new ArrayList<String>(); 223 treeConfigs.addAll(treeConfigDescriptors.keySet()); 224 return treeConfigs; 225 } 226 227 @Override 228 public Map<String, String> getAvailablePublicationTrees() { 229 Map<String, String> trees = new HashMap<String, String>(); 230 for (PublicationTreeConfigDescriptor desc : treeConfigDescriptors.values()) { 231 String title = desc.getTitle() == null ? desc.getName() : desc.getTitle(); 232 trees.put(desc.getName(), title); 233 } 234 return trees; 235 } 236 237 @Override 238 public PublicationTree getPublicationTree(String treeName, CoreSession coreSession, Map<String, String> params) 239 throws PublicationTreeNotAvailable { 240 return getPublicationTree(treeName, coreSession, params, null); 241 } 242 243 @Override 244 public PublicationTree getPublicationTree(String treeName, CoreSession coreSession, Map<String, String> params, 245 DocumentModel currentDocument) throws PublicationTreeNotAvailable { 246 PublicationTree tree = getOrBuildTree(treeName, coreSession, params); 247 if (tree == null) { 248 return null; 249 } 250 if (currentDocument != null) { 251 tree.setCurrentDocument(currentDocument); 252 } 253 return new ProxyTree(tree, tree.getSessionId()); 254 } 255 256 @Override 257 public Map<String, String> initRemoteSession(String treeConfigName, Map<String, String> params) { 258 CoreSession coreSession = CoreInstance.openCoreSession(null); 259 PublicationTree tree = getPublicationTree(treeConfigName, coreSession, params); 260 261 remoteLiveTrees.put(tree.getSessionId(), coreSession.getSessionId()); 262 263 Map<String, String> res = new HashMap<String, String>(); 264 res.put("sessionId", tree.getSessionId()); 265 res.put("title", tree.getTitle()); 266 res.put("nodeType", tree.getNodeType()); 267 res.put("treeName", tree.getConfigName()); 268 res.put("path", tree.getPath()); 269 270 return res; 271 } 272 273 @Override 274 public void release(String sid) { 275 PublicationTree tree; 276 277 if (liveTrees.containsKey(sid)) { 278 tree = liveTrees.get(sid); 279 tree.release(); 280 liveTrees.remove(sid); 281 } 282 if (remoteLiveTrees.containsKey(sid)) { 283 // close here session opened for remote trees 284 String sessionId = remoteLiveTrees.get(sid); 285 CoreSession remoteSession = CoreInstance.getInstance().getSession(sessionId); 286 remoteSession.close(); 287 remoteLiveTrees.remove(sid); 288 } 289 } 290 291 @Override 292 public void releaseAllTrees(String sessionId) { 293 for (String configName : treeConfigDescriptors.keySet()) { 294 String treeid = computeTreeSessionId(configName, sessionId); 295 release(treeid); 296 } 297 } 298 299 protected PublicationTree getOrBuildTree(String treeConfigName, CoreSession coreSession, Map<String, String> params) 300 throws PublicationTreeNotAvailable { 301 String key = computeTreeSessionId(treeConfigName, coreSession); 302 PublicationTree tree; 303 if (liveTrees.containsKey(key)) { 304 tree = liveTrees.get(key); 305 } else { 306 tree = buildTree(key, treeConfigName, coreSession, params); 307 if (tree != null) { 308 liveTrees.put(key, tree); 309 } 310 } 311 return tree; 312 } 313 314 protected PublicationTree buildTree(String sid, String treeConfigName, CoreSession coreSession, 315 Map<String, String> params) throws PublicationTreeNotAvailable { 316 PublicationTreeConfigDescriptor config = getPublicationTreeConfigDescriptor(treeConfigName); 317 Map<String, String> allParameters = computeAllParameters(config, params); 318 PublicationTreeDescriptor treeDescriptor = getPublicationTreeDescriptor(config); 319 PublishedDocumentFactory publishedDocumentFactory = getPublishedDocumentFactory(config, treeDescriptor, 320 coreSession, allParameters); 321 return getPublicationTree(treeDescriptor, sid, coreSession, allParameters, publishedDocumentFactory, 322 config.getName(), config.getTitle()); 323 } 324 325 protected Map<String, String> computeAllParameters(PublicationTreeConfigDescriptor config, 326 Map<String, String> params) { 327 final Map<String, String> allParameters = config.getParameters(); 328 if (params != null) { 329 allParameters.putAll(params); 330 } 331 return allParameters; 332 } 333 334 protected PublishedDocumentFactory getPublishedDocumentFactory(PublicationTreeConfigDescriptor config, 335 PublicationTreeDescriptor treeDescriptor, CoreSession coreSession, Map<String, String> params) { 336 PublishedDocumentFactoryDescriptor factoryDesc = getPublishedDocumentFactoryDescriptor(config, treeDescriptor); 337 ValidatorsRule validatorsRule = getValidatorsRule(factoryDesc); 338 339 PublishedDocumentFactory factory; 340 try { 341 factory = factoryDesc.getKlass().newInstance(); 342 } catch (ReflectiveOperationException e) { 343 throw new NuxeoException("Error while creating factory " + factoryDesc.getName(), e); 344 } 345 factory.init(coreSession, validatorsRule, params); 346 return factory; 347 } 348 349 protected ValidatorsRule getValidatorsRule(PublishedDocumentFactoryDescriptor factoryDesc) { 350 String validatorsRuleName = factoryDesc.getValidatorsRuleName(); 351 ValidatorsRule validatorsRule = null; 352 if (validatorsRuleName != null) { 353 ValidatorsRuleDescriptor validatorsRuleDesc = validatorsRuleDescriptors.get(validatorsRuleName); 354 if (validatorsRuleDesc == null) { 355 throw new NuxeoException("Unable to find validatorsRule" + validatorsRuleName); 356 } 357 try { 358 validatorsRule = validatorsRuleDesc.getKlass().newInstance(); 359 } catch (ReflectiveOperationException e) { 360 throw new NuxeoException("Error while creating validatorsRule " + validatorsRuleName, e); 361 } 362 } 363 return validatorsRule; 364 } 365 366 protected PublishedDocumentFactoryDescriptor getPublishedDocumentFactoryDescriptor( 367 PublicationTreeConfigDescriptor config, PublicationTreeDescriptor treeDescriptor) { 368 String factoryName = config.getFactory(); 369 if (factoryName == null) { 370 factoryName = treeDescriptor.getFactory(); 371 } 372 373 PublishedDocumentFactoryDescriptor factoryDesc = factoryDescriptors.get(factoryName); 374 if (factoryDesc == null) { 375 throw new NuxeoException("Unable to find factory" + factoryName); 376 } 377 return factoryDesc; 378 } 379 380 protected PublicationTreeConfigDescriptor getPublicationTreeConfigDescriptor(String treeConfigName) { 381 if (!treeConfigDescriptors.containsKey(treeConfigName)) { 382 throw new NuxeoException("Unknow treeConfig :" + treeConfigName); 383 } 384 return treeConfigDescriptors.get(treeConfigName); 385 } 386 387 protected PublicationTreeDescriptor getPublicationTreeDescriptor(PublicationTreeConfigDescriptor config) { 388 String treeImplName = config.getTree(); 389 if (!treeDescriptors.containsKey(treeImplName)) { 390 throw new NuxeoException("Unknow treeImplementation :" + treeImplName); 391 } 392 return treeDescriptors.get(treeImplName); 393 } 394 395 protected PublicationTree getPublicationTree(PublicationTreeDescriptor treeDescriptor, String sid, 396 CoreSession coreSession, Map<String, String> parameters, PublishedDocumentFactory factory, 397 String configName, String treeTitle) throws PublicationTreeNotAvailable { 398 PublicationTree treeImpl; 399 try { 400 treeImpl = treeDescriptor.getKlass().newInstance(); 401 } catch (ReflectiveOperationException e) { 402 throw new NuxeoException("Error while creating tree implementation", e); 403 } 404 treeImpl.initTree(sid, coreSession, parameters, factory, configName, treeTitle); 405 return treeImpl; 406 } 407 408 @Override 409 public PublishedDocument publish(DocumentModel doc, PublicationNode targetNode) { 410 return publish(doc, targetNode, null); 411 } 412 413 @Override 414 public PublishedDocument publish(DocumentModel doc, PublicationNode targetNode, Map<String, String> params) { 415 416 PublicationTree tree = liveTrees.get(targetNode.getSessionId()); 417 if (tree != null) { 418 return tree.publish(doc, targetNode, params); 419 } else { 420 throw new NuxeoException("Calling getChildrenNodes on a closed tree"); 421 } 422 } 423 424 @Override 425 public void unpublish(DocumentModel doc, PublicationNode targetNode) { 426 PublicationTree tree = liveTrees.get(targetNode.getSessionId()); 427 if (tree != null) { 428 tree.unpublish(doc, targetNode); 429 } else { 430 throw new NuxeoException("Calling getChildrenNodes on a closed tree"); 431 } 432 } 433 434 @Override 435 public void unpublish(String sid, PublishedDocument publishedDocument) { 436 PublicationTree tree = liveTrees.get(sid); 437 if (tree != null) { 438 tree.unpublish(publishedDocument); 439 } else { 440 throw new NuxeoException("Calling getChildrenNodes on a closed tree"); 441 } 442 } 443 444 @Override 445 public List<PublishedDocument> getChildrenDocuments(PublicationNode node) { 446 447 PublicationTree tree = liveTrees.get(node.getSessionId()); 448 if (tree != null) { 449 return tree.getPublishedDocumentInNode(tree.getNodeByPath(node.getPath())); 450 } else { 451 throw new NuxeoException("Calling getChildrenDocuments on a closed tree"); 452 } 453 } 454 455 protected List<PublicationNode> makeRemotable(List<PublicationNode> nodes, String sid) { 456 List<PublicationNode> remoteNodes = new ArrayList<PublicationNode>(); 457 458 for (PublicationNode node : nodes) { 459 remoteNodes.add(new ProxyNode(node, sid)); 460 } 461 462 return remoteNodes; 463 } 464 465 @Override 466 public List<PublicationNode> getChildrenNodes(PublicationNode node) { 467 String sid = node.getSessionId(); 468 PublicationTree tree = liveTrees.get(sid); 469 if (tree != null) { 470 return makeRemotable(tree.getNodeByPath(node.getPath()).getChildrenNodes(), sid); 471 } else { 472 throw new NuxeoException("Calling getChildrenNodes on a closed tree"); 473 } 474 } 475 476 @Override 477 public PublicationNode getParent(PublicationNode node) { 478 String sid = node.getSessionId(); 479 PublicationTree tree = liveTrees.get(sid); 480 if (tree != null) { 481 PublicationNode liveNode; 482 liveNode = tree.getNodeByPath(node.getPath()).getParent(); 483 if (liveNode == null) { 484 return null; 485 } 486 return new ProxyNode(liveNode, sid); 487 } else { 488 log.error("Calling getParent on a closed tree"); 489 return null; 490 } 491 } 492 493 @Override 494 public PublicationNode getNodeByPath(String sid, String path) { 495 PublicationTree tree = liveTrees.get(sid); 496 if (tree != null) { 497 return new ProxyNode(tree.getNodeByPath(path), sid); 498 } else { 499 throw new NuxeoException("Calling getNodeByPath on a closed tree"); 500 } 501 } 502 503 @Override 504 public List<PublishedDocument> getExistingPublishedDocument(String sid, DocumentLocation docLoc) { 505 PublicationTree tree = liveTrees.get(sid); 506 if (tree != null) { 507 return tree.getExistingPublishedDocument(docLoc); 508 } else { 509 throw new NuxeoException("Calling getNodeByPath on a closed tree"); 510 } 511 } 512 513 @Override 514 public List<PublishedDocument> getPublishedDocumentInNode(PublicationNode node) { 515 String sid = node.getSessionId(); 516 PublicationTree tree = liveTrees.get(sid); 517 if (tree != null) { 518 return tree.getPublishedDocumentInNode(tree.getNodeByPath(node.getPath())); 519 } else { 520 throw new NuxeoException("Calling getPublishedDocumentInNode on a closed tree"); 521 } 522 } 523 524 @Override 525 public void setCurrentDocument(String sid, DocumentModel currentDocument) { 526 PublicationTree tree = liveTrees.get(sid); 527 if (tree != null) { 528 tree.setCurrentDocument(currentDocument); 529 } else { 530 throw new NuxeoException("Calling validatorPublishDocument on a closed tree"); 531 } 532 } 533 534 @Override 535 public void validatorPublishDocument(String sid, PublishedDocument publishedDocument, String comment) { 536 PublicationTree tree = liveTrees.get(sid); 537 if (tree != null) { 538 tree.validatorPublishDocument(publishedDocument, comment); 539 } else { 540 throw new NuxeoException("Calling validatorPublishDocument on a closed tree"); 541 } 542 } 543 544 @Override 545 public void validatorRejectPublication(String sid, PublishedDocument publishedDocument, String comment) { 546 PublicationTree tree = liveTrees.get(sid); 547 if (tree != null) { 548 tree.validatorRejectPublication(publishedDocument, comment); 549 } else { 550 throw new NuxeoException("Calling validatorPublishDocument on a closed tree"); 551 } 552 } 553 554 @Override 555 public boolean canPublishTo(String sid, PublicationNode publicationNode) { 556 PublicationTree tree = liveTrees.get(sid); 557 if (tree != null) { 558 return tree.canPublishTo(publicationNode); 559 } else { 560 throw new NuxeoException("Calling validatorPublishDocument on a closed tree"); 561 } 562 } 563 564 @Override 565 public boolean canUnpublish(String sid, PublishedDocument publishedDocument) { 566 PublicationTree tree = liveTrees.get(sid); 567 if (tree != null) { 568 return tree.canUnpublish(publishedDocument); 569 } else { 570 throw new NuxeoException("Calling validatorPublishDocument on a closed tree"); 571 } 572 } 573 574 @Override 575 public boolean canManagePublishing(String sid, PublishedDocument publishedDocument) { 576 PublicationTree tree = liveTrees.get(sid); 577 if (tree != null) { 578 return tree.canManagePublishing(publishedDocument); 579 } else { 580 throw new NuxeoException("Calling validatorPublishDocument on a closed tree"); 581 } 582 } 583 584 @Override 585 public boolean isPublishedDocument(DocumentModel documentModel) { 586 return PublicationRelationHelper.isPublished(documentModel); 587 } 588 589 @Override 590 public PublicationTree getPublicationTreeFor(DocumentModel doc, CoreSession coreSession) { 591 PublicationTree tree = null; 592 try { 593 tree = PublicationRelationHelper.getPublicationTreeUsedForPublishing(doc, coreSession); 594 } catch (NuxeoException e) { 595 // TODO catch proper exception 596 log.error("Unable to get PublicationTree for " + doc.getPathAsString() 597 + ". Fallback on first PublicationTree accepting this document.", e); 598 for (String treeName : treeConfigDescriptors.keySet()) { 599 tree = getPublicationTree(treeName, coreSession, null); 600 if (tree.isPublicationNode(doc)) { 601 break; 602 } 603 } 604 } 605 return tree; 606 } 607 608 @Override 609 public boolean hasValidationTask(String sid, PublishedDocument publishedDocument) { 610 PublicationTree tree = liveTrees.get(sid); 611 if (tree != null) { 612 return tree.hasValidationTask(publishedDocument); 613 } else { 614 throw new NuxeoException("Calling validatorPublishDocument on a closed tree"); 615 } 616 } 617 618 @Override 619 public PublishedDocument wrapToPublishedDocument(String sid, DocumentModel documentModel) { 620 PublicationTree tree = liveTrees.get(sid); 621 if (tree != null) { 622 return tree.wrapToPublishedDocument(documentModel); 623 } else { 624 throw new NuxeoException("Calling validatorPublishDocument on a closed tree"); 625 } 626 } 627 628 @Override 629 public boolean isPublicationNode(String sid, DocumentModel documentModel) { 630 PublicationTree tree = liveTrees.get(sid); 631 if (tree != null) { 632 return tree.isPublicationNode(documentModel); 633 } else { 634 throw new NuxeoException("Calling validatorPublishDocument on a closed tree"); 635 } 636 } 637 638 @Override 639 public PublicationNode wrapToPublicationNode(String sid, DocumentModel documentModel) { 640 PublicationTree tree = liveTrees.get(sid); 641 if (tree != null) { 642 return tree.wrapToPublicationNode(documentModel); 643 } else { 644 throw new NuxeoException("Calling validatorPublishDocument on a closed tree"); 645 } 646 } 647 648 @Override 649 public PublicationNode wrapToPublicationNode(DocumentModel documentModel, CoreSession coreSession) 650 throws PublicationTreeNotAvailable { 651 for (String name : getAvailablePublicationTree()) { 652 PublicationTree tree = getPublicationTree(name, coreSession, null); 653 PublicationTreeConfigDescriptor config = treeConfigDescriptors.get(tree.getConfigName()); 654 if (!config.islocalSectionTree()) { 655 // ignore all non local section tree 656 continue; 657 } 658 if (tree.isPublicationNode(documentModel)) { 659 return tree.wrapToPublicationNode(documentModel); 660 } 661 } 662 return null; 663 } 664 665 protected void registerPendingDescriptors() { 666 // TODO what to do with multiple repositories? 667 RepositoryManager repositoryManager = Framework.getService(RepositoryManager.class); 668 String repositoryName = repositoryManager.getDefaultRepositoryName(); 669 List<DocumentModel> domains = new DomainsFinder(repositoryName).getDomains(); 670 for (DocumentModel domain : domains) { 671 registerTreeConfigFor(domain); 672 } 673 } 674 675 public void registerTreeConfigFor(DocumentModel domain) { 676 for (PublicationTreeConfigDescriptor desc : pendingDescriptors.values()) { 677 PublicationTreeConfigDescriptor newDesc = new PublicationTreeConfigDescriptor(desc); 678 String newTreeName = desc.getName() + "-" + domain.getName(); 679 newDesc.setName(newTreeName); 680 Path newPath = domain.getPath(); 681 Map<String, String> parameters = newDesc.getParameters(); 682 newPath = newPath.append(parameters.remove(RELATIVE_ROOT_PATH_KEY)); 683 parameters.put(ROOT_PATH_KEY, newPath.toString()); 684 parameters.put(PublisherService.DOMAIN_NAME_KEY, domain.getTitle()); 685 treeConfigDescriptors.put(newDesc.getName(), newDesc); 686 } 687 } 688 689 public void unRegisterTreeConfigFor(DocumentModel domain) { 690 unRegisterTreeConfigFor(domain.getName()); 691 } 692 693 /** 694 * @since 7.3 695 */ 696 public void unRegisterTreeConfigFor(String domainName) { 697 for (PublicationTreeConfigDescriptor desc : pendingDescriptors.values()) { 698 String treeName = desc.getName() + "-" + domainName; 699 treeConfigDescriptors.remove(treeName); 700 for (Iterator<String> it = liveTrees.keySet().iterator(); it.hasNext();) { 701 String entry = it.next(); 702 if (entry.startsWith(treeName)) { 703 it.remove(); 704 } 705 } 706 } 707 } 708 709 @Override 710 public Map<String, String> getParametersFor(String treeConfigName) { 711 PublicationTreeConfigDescriptor desc = treeConfigDescriptors.get(treeConfigName); 712 Map<String, String> parameters = new HashMap<String, String>(); 713 if (desc != null) { 714 parameters.putAll(desc.getParameters()); 715 } 716 return parameters; 717 } 718 719 @Override 720 public RootSectionFinder getRootSectionFinder(CoreSession session) { 721 if (rootSectionFinderFactory != null) { 722 return rootSectionFinderFactory.getRootSectionFinder(session); 723 } 724 return new DefaultRootSectionsFinder(session); 725 } 726}