001/* 002 * (C) Copyright 2006-2008 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 * Alexandre Russel 018 * 019 * $Id$ 020 */ 021 022package org.nuxeo.ecm.platform.annotations.proxy; 023 024import java.net.MalformedURLException; 025import java.net.URI; 026import java.util.ArrayList; 027import java.util.List; 028 029import org.apache.commons.logging.Log; 030import org.apache.commons.logging.LogFactory; 031import org.nuxeo.ecm.core.api.NuxeoException; 032import org.nuxeo.ecm.core.api.NuxeoPrincipal; 033import org.nuxeo.ecm.platform.annotations.api.Annotation; 034import org.nuxeo.ecm.platform.annotations.api.AnnotationManager; 035import org.nuxeo.ecm.platform.annotations.api.AnnotationsService; 036import org.nuxeo.ecm.platform.annotations.api.UriResolver; 037import org.nuxeo.ecm.platform.annotations.service.AnnotabilityManager; 038import org.nuxeo.ecm.platform.annotations.service.AnnotationConfigurationService; 039import org.nuxeo.ecm.platform.annotations.service.AnnotationsServiceImpl; 040import org.nuxeo.ecm.platform.annotations.service.EventListener; 041import org.nuxeo.ecm.platform.annotations.service.PermissionManager; 042import org.nuxeo.ecm.platform.annotations.service.URLPatternFilter; 043import org.nuxeo.ecm.platform.relations.api.Graph; 044import org.nuxeo.runtime.api.Framework; 045 046/** 047 * @author <a href="mailto:[email protected]">Alexandre Russel</a> 048 */ 049public class AnnotationServiceProxy implements AnnotationsService { 050 051 private static final Log log = LogFactory.getLog(AnnotationServiceProxy.class); 052 053 private final AnnotationManager annotationManager = new AnnotationManager(); 054 055 private AnnotationConfigurationService configurationService; 056 057 private AnnotabilityManager annotabilityManager; 058 059 private AnnotationsServiceImpl service; 060 061 private URLPatternFilter filter; 062 063 private UriResolver resolver; 064 065 private PermissionManager permissionManager; 066 067 private List<EventListener> listeners; 068 069 public void initialise() { 070 service = new AnnotationsServiceImpl(); 071 configurationService = Framework.getService(AnnotationConfigurationService.class); 072 filter = configurationService.getUrlPatternFilter(); 073 resolver = configurationService.getUriResolver(); 074 annotabilityManager = configurationService.getAnnotabilityManager(); 075 permissionManager = configurationService.getPermissionManager(); 076 listeners = configurationService.getListeners(); 077 } 078 079 @Override 080 public Annotation addAnnotation(Annotation annotation, NuxeoPrincipal user, String baseUrl) { 081 checkUrl(annotation); 082 Annotation translatedAnnotation = getTranslatedAnnotation(annotation); 083 if (!annotabilityManager.isAnnotable(annotation.getAnnotates())) { 084 throw new NuxeoException("Not annotable uri: " + annotation.getAnnotates()); 085 } 086 checkPermission(annotation, user, configurationService.getCreateAnnotationPermission()); 087 for (EventListener listener : listeners) { 088 listener.beforeAnnotationCreated(user, translatedAnnotation); 089 } 090 Annotation tmpResult = service.addAnnotation(translatedAnnotation, user, baseUrl); 091 for (EventListener listener : listeners) { 092 listener.afterAnnotationCreated(user, tmpResult); 093 } 094 return annotationManager.translateAnnotationFromRepo(resolver, baseUrl, tmpResult); 095 } 096 097 private void checkPermission(Annotation annotation, NuxeoPrincipal user, String permission) { 098 if (!permissionManager.check(user, permission, annotation.getAnnotates())) { 099 throw new NuxeoException(user + " allowed to query annotation."); 100 } 101 } 102 103 private Annotation getTranslatedAnnotation(Annotation annotation) { 104 Annotation translatedAnnotation = annotationManager.translateAnnotationToRepo(resolver, annotation); 105 return translatedAnnotation; 106 } 107 108 private void checkUrl(Annotation annotation) { 109 try { 110 URI uri = annotation.getAnnotates(); 111 if (uri.toASCIIString().startsWith("urn:")) { 112 return; 113 } 114 String url = uri.toURL().toString(); 115 if (!filter.allow(url)) { 116 throw new NuxeoException("Not allowed to annotate: " + url); 117 } 118 } catch (MalformedURLException e) { 119 throw new NuxeoException(e); 120 } 121 } 122 123 @Override 124 public void deleteAnnotation(Annotation annotation, NuxeoPrincipal user) { 125 checkPermission(annotation, user, configurationService.getDeleteAnnotationPermission()); 126 Annotation translatedAnnotation = getTranslatedAnnotation(annotation); 127 for (EventListener listener : listeners) { 128 listener.beforeAnnotationDeleted(user, translatedAnnotation); 129 } 130 service.deleteAnnotation(translatedAnnotation, user); 131 for (EventListener listener : listeners) { 132 listener.afterAnnotationDeleted(user, translatedAnnotation); 133 } 134 } 135 136 @Override 137 public void deleteAnnotationFor(URI uri, Annotation annotation, NuxeoPrincipal user) { 138 checkPermission(annotation, user, configurationService.getDeleteAnnotationPermission()); 139 Annotation translatedAnnotation = getTranslatedAnnotation(annotation); 140 for (EventListener listener : listeners) { 141 listener.beforeAnnotationDeleted(user, translatedAnnotation); 142 } 143 service.deleteAnnotationFor(resolver.translateToGraphURI(uri), translatedAnnotation, user); 144 for (EventListener listener : listeners) { 145 listener.afterAnnotationDeleted(user, translatedAnnotation); 146 } 147 } 148 149 @Override 150 public Annotation getAnnotation(String annotationId, NuxeoPrincipal user, String baseUrl) { 151 for (EventListener listener : listeners) { 152 listener.beforeAnnotationRead(user, annotationId); 153 } 154 Annotation result = service.getAnnotation(annotationId, user, null); 155 checkPermission(result, user, configurationService.getReadAnnotationPermission()); 156 for (EventListener listener : listeners) { 157 listener.afterAnnotationRead(user, result); 158 } 159 return annotationManager.translateAnnotationFromRepo(resolver, baseUrl, result); 160 } 161 162 @Override 163 public Graph getAnnotationGraph() { 164 return service.getAnnotationGraph(); 165 } 166 167 @Override 168 public List<Annotation> queryAnnotations(URI uri, NuxeoPrincipal user) { 169 String baseUrl = null; 170 if (!uri.toString().startsWith("urn")) { 171 baseUrl = resolver.getBaseUrl(uri); 172 } 173 List<Annotation> tempResult = service.queryAnnotations(resolver.translateToGraphURI(uri), user); 174 List<Annotation> result = new ArrayList<Annotation>(); 175 for (Annotation annotation : tempResult) { 176 Annotation translatedAnnotation = annotationManager.translateAnnotationFromRepo(resolver, baseUrl, 177 annotation); 178 for (EventListener listener : listeners) { 179 listener.afterAnnotationRead(user, translatedAnnotation); 180 } 181 checkPermission(translatedAnnotation, user, configurationService.getReadAnnotationPermission()); 182 result.add(translatedAnnotation); 183 } 184 return result; 185 } 186 187 @Override 188 public int getAnnotationsCount(URI uri, NuxeoPrincipal user) { 189 String baseUrl = null; 190 if (!uri.toString().startsWith("urn")) { 191 baseUrl = resolver.getBaseUrl(uri); 192 } 193 return service.getAnnotationsCount(resolver.translateToGraphURI(uri), user); 194 } 195 196 @Override 197 public Annotation updateAnnotation(Annotation annotation, NuxeoPrincipal user, String baseUrl) { 198 checkPermission(annotation, user, configurationService.getUpdateAnnotationPermission()); 199 for (EventListener listener : listeners) { 200 listener.beforeAnnotationUpdated(user, annotation); 201 } 202 Annotation result = service.updateAnnotation(getTranslatedAnnotation(annotation), user, baseUrl); 203 for (EventListener listener : listeners) { 204 listener.afterAnnotationUpdated(user, result); 205 } 206 return annotationManager.translateAnnotationFromRepo(resolver, baseUrl, result); 207 } 208}