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