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