001/* 002 * Copyright (c) 2006-2011 Nuxeo SA (http://nuxeo.com/) and others. 003 * 004 * All rights reserved. This program and the accompanying materials 005 * are made available under the terms of the Eclipse Public License v1.0 006 * which accompanies this distribution, and is available at 007 * http://www.eclipse.org/legal/epl-v10.html 008 * 009 * Contributors: 010 * Florent Guillaume 011 */ 012package org.nuxeo.ecm.core.api.pathsegment; 013 014import java.util.LinkedList; 015 016import org.apache.commons.logging.Log; 017import org.apache.commons.logging.LogFactory; 018import org.nuxeo.ecm.core.api.DocumentModel; 019import org.nuxeo.ecm.core.api.NuxeoException; 020import org.nuxeo.runtime.model.ComponentContext; 021import org.nuxeo.runtime.model.ComponentInstance; 022import org.nuxeo.runtime.model.DefaultComponent; 023 024/** 025 * Central service for the generation of a path segment for a document. 026 */ 027public class PathSegmentComponent extends DefaultComponent implements PathSegmentService { 028 029 private static final Log log = LogFactory.getLog(PathSegmentComponent.class); 030 031 public static final String XP = "pathSegmentService"; 032 033 protected LinkedList<Class<? extends PathSegmentService>> contribs; 034 035 protected PathSegmentService service; 036 037 protected boolean recompute; 038 039 @Override 040 public void activate(ComponentContext context) { 041 contribs = new LinkedList<Class<? extends PathSegmentService>>(); 042 recompute = true; 043 service = null; 044 } 045 046 @Override 047 public void deactivate(ComponentContext context) { 048 contribs.clear(); 049 service = null; 050 } 051 052 @Override 053 @SuppressWarnings("unchecked") 054 public void registerContribution(Object contrib, String xp, ComponentInstance contributor) { 055 if (!XP.equals(xp)) { 056 log.error("Unknown extension point " + xp); 057 return; 058 } 059 if (!(contrib instanceof PathSegmentServiceDescriptor)) { 060 log.error("Invalid contribution: " + contrib.getClass().getName()); 061 return; 062 } 063 PathSegmentServiceDescriptor desc = (PathSegmentServiceDescriptor) contrib; 064 Class<?> klass; 065 try { 066 klass = Class.forName(desc.className); 067 } catch (ClassNotFoundException e) { 068 log.error("Invalid contribution class: " + desc.className); 069 return; 070 } 071 if (!PathSegmentService.class.isAssignableFrom(klass)) { 072 log.error("Invalid contribution class: " + desc.className); 073 return; 074 } 075 contribs.add((Class<PathSegmentService>) klass); 076 log.info("Registered path segment service: " + desc.className); 077 recompute = true; 078 } 079 080 @Override 081 public void unregisterContribution(Object contrib, String xp, ComponentInstance contributor) { 082 if (!XP.equals(xp)) { 083 return; 084 } 085 if (!(contrib instanceof PathSegmentServiceDescriptor)) { 086 return; 087 } 088 PathSegmentServiceDescriptor desc = (PathSegmentServiceDescriptor) contrib; 089 Class<?> klass; 090 try { 091 klass = Class.forName(desc.className); 092 } catch (ClassNotFoundException e) { 093 return; 094 } 095 if (!klass.isAssignableFrom(PathSegmentService.class)) { 096 return; 097 } 098 contribs.remove(klass); 099 log.info("Unregistered path segment service: " + desc.className); 100 recompute = true; 101 } 102 103 @Override 104 public String generatePathSegment(DocumentModel doc) { 105 if (recompute) { 106 recompute(); 107 recompute = false; 108 } 109 return service.generatePathSegment(doc); 110 } 111 112 protected void recompute() { 113 Class<? extends PathSegmentService> klass; 114 if (contribs.isEmpty()) { 115 klass = PathSegmentServiceDefault.class; 116 } else { 117 klass = contribs.getLast(); 118 } 119 if (service == null || klass != service.getClass()) { 120 try { 121 service = klass.newInstance(); 122 } catch (ReflectiveOperationException e) { 123 throw new NuxeoException(e); 124 } 125 } // else keep old service instance 126 } 127 128 @Override 129 public String generatePathSegment(String s) { 130 if (recompute) { 131 recompute(); 132 recompute = false; 133 } 134 return service.generatePathSegment(s); 135 } 136 137 @Override 138 public int getMaxSize() { 139 if (recompute) { 140 recompute(); 141 recompute = false; 142 } 143 return service.getMaxSize(); 144 } 145}