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; 028import java.util.Map; 029 030import org.apache.commons.logging.Log; 031import org.apache.commons.logging.LogFactory; 032import org.nuxeo.ecm.core.api.NuxeoException; 033import org.nuxeo.ecm.core.api.NuxeoPrincipal; 034import org.nuxeo.ecm.platform.annotations.api.Annotation; 035import org.nuxeo.ecm.platform.annotations.api.AnnotationManager; 036import org.nuxeo.ecm.platform.annotations.api.AnnotationsService; 037import org.nuxeo.ecm.platform.annotations.api.UriResolver; 038import org.nuxeo.ecm.platform.annotations.service.AnnotabilityManager; 039import org.nuxeo.ecm.platform.annotations.service.AnnotationConfigurationService; 040import org.nuxeo.ecm.platform.annotations.service.AnnotationsServiceImpl; 041import org.nuxeo.ecm.platform.annotations.service.EventListener; 042import org.nuxeo.ecm.platform.annotations.service.PermissionManager; 043import org.nuxeo.ecm.platform.annotations.service.URLPatternFilter; 044import org.nuxeo.ecm.platform.relations.api.Graph; 045import org.nuxeo.runtime.api.Framework; 046 047/** 048 * @author <a href="mailto:arussel@nuxeo.com">Alexandre Russel</a> 049 */ 050public class AnnotationServiceProxy implements AnnotationsService { 051 052 private static final Log log = LogFactory.getLog(AnnotationServiceProxy.class); 053 054 private final AnnotationManager annotationManager = new AnnotationManager(); 055 056 private AnnotationConfigurationService configurationService; 057 058 private AnnotabilityManager annotabilityManager; 059 060 private AnnotationsServiceImpl service; 061 062 private URLPatternFilter filter; 063 064 private UriResolver resolver; 065 066 private PermissionManager permissionManager; 067 068 private List<EventListener> listeners; 069 070 public void initialise() { 071 service = new AnnotationsServiceImpl(); 072 configurationService = Framework.getService(AnnotationConfigurationService.class); 073 filter = configurationService.getUrlPatternFilter(); 074 resolver = configurationService.getUriResolver(); 075 annotabilityManager = configurationService.getAnnotabilityManager(); 076 permissionManager = configurationService.getPermissionManager(); 077 listeners = configurationService.getListeners(); 078 } 079 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 public void deleteAnnotation(Annotation annotation, NuxeoPrincipal user) { 124 checkPermission(annotation, user, configurationService.getDeleteAnnotationPermission()); 125 Annotation translatedAnnotation = getTranslatedAnnotation(annotation); 126 for (EventListener listener : listeners) { 127 listener.beforeAnnotationDeleted(user, translatedAnnotation); 128 } 129 service.deleteAnnotation(translatedAnnotation, user); 130 for (EventListener listener : listeners) { 131 listener.afterAnnotationDeleted(user, translatedAnnotation); 132 } 133 } 134 135 public void deleteAnnotationFor(URI uri, Annotation annotation, NuxeoPrincipal user) { 136 checkPermission(annotation, user, configurationService.getDeleteAnnotationPermission()); 137 Annotation translatedAnnotation = getTranslatedAnnotation(annotation); 138 for (EventListener listener : listeners) { 139 listener.beforeAnnotationDeleted(user, translatedAnnotation); 140 } 141 service.deleteAnnotationFor(resolver.translateToGraphURI(uri), translatedAnnotation, user); 142 for (EventListener listener : listeners) { 143 listener.afterAnnotationDeleted(user, translatedAnnotation); 144 } 145 } 146 147 public Annotation getAnnotation(String annotationId, NuxeoPrincipal user, String baseUrl) { 148 for (EventListener listener : listeners) { 149 listener.beforeAnnotationRead(user, annotationId); 150 } 151 Annotation result = service.getAnnotation(annotationId, user, null); 152 checkPermission(result, user, configurationService.getReadAnnotationPermission()); 153 for (EventListener listener : listeners) { 154 listener.afterAnnotationRead(user, result); 155 } 156 return annotationManager.translateAnnotationFromRepo(resolver, baseUrl, result); 157 } 158 159 public Graph getAnnotationGraph() { 160 return service.getAnnotationGraph(); 161 } 162 163 public List<Annotation> queryAnnotations(URI uri, NuxeoPrincipal user) { 164 String baseUrl = null; 165 if (!uri.toString().startsWith("urn")) { 166 baseUrl = resolver.getBaseUrl(uri); 167 } 168 List<Annotation> tempResult = service.queryAnnotations(resolver.translateToGraphURI(uri), user); 169 List<Annotation> result = new ArrayList<Annotation>(); 170 for (Annotation annotation : tempResult) { 171 Annotation translatedAnnotation = annotationManager.translateAnnotationFromRepo(resolver, baseUrl, 172 annotation); 173 for (EventListener listener : listeners) { 174 listener.afterAnnotationRead(user, translatedAnnotation); 175 } 176 checkPermission(translatedAnnotation, user, configurationService.getReadAnnotationPermission()); 177 result.add(translatedAnnotation); 178 } 179 return result; 180 } 181 182 @Override 183 public int getAnnotationsCount(URI uri, NuxeoPrincipal user) { 184 String baseUrl = null; 185 if (!uri.toString().startsWith("urn")) { 186 baseUrl = resolver.getBaseUrl(uri); 187 } 188 return service.getAnnotationsCount(resolver.translateToGraphURI(uri), user); 189 } 190 191 public Annotation updateAnnotation(Annotation annotation, NuxeoPrincipal user, String baseUrl) { 192 checkPermission(annotation, user, configurationService.getUpdateAnnotationPermission()); 193 for (EventListener listener : listeners) { 194 listener.beforeAnnotationUpdated(user, annotation); 195 } 196 Annotation result = service.updateAnnotation(getTranslatedAnnotation(annotation), user, baseUrl); 197 for (EventListener listener : listeners) { 198 listener.afterAnnotationUpdated(user, result); 199 } 200 return annotationManager.translateAnnotationFromRepo(resolver, baseUrl, result); 201 } 202}