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