001/* 002 * (C) Copyright 2006-2015 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 - initial API and implementation 018 * 019 */ 020 021package org.nuxeo.ecm.directory; 022 023import java.util.ArrayList; 024import java.util.Collection; 025import java.util.Collections; 026import java.util.HashMap; 027import java.util.List; 028import java.util.Map; 029 030import org.nuxeo.ecm.core.api.DocumentModel; 031import org.nuxeo.ecm.core.api.DocumentModelComparator; 032import org.nuxeo.runtime.metrics.MetricsService; 033 034import com.codahale.metrics.Counter; 035import com.codahale.metrics.MetricRegistry; 036import com.codahale.metrics.SharedMetricRegistries; 037 038public abstract class AbstractDirectory implements Directory { 039 040 public final String name; 041 042 protected DirectoryFieldMapper fieldMapper; 043 044 protected final Map<String, List<Reference>> references = new HashMap<>(); 045 046 // simple cache system for entry lookups, disabled by default 047 protected final DirectoryCache cache; 048 049 // @since 5.7 050 protected final MetricRegistry registry = SharedMetricRegistries.getOrCreate(MetricsService.class.getName()); 051 052 protected final Counter sessionCount; 053 054 protected final Counter sessionMaxCount; 055 056 protected AbstractDirectory(String name) { 057 this.name = name; 058 cache = new DirectoryCache(name); 059 sessionCount = registry.counter(MetricRegistry.name("nuxeo", "directories", name, "sessions", "active")); 060 061 sessionMaxCount = registry.counter(MetricRegistry.name("nuxeo", "directories", name, "sessions", "max")); 062 } 063 064 /** 065 * Invalidate my cache and the caches of linked directories by references. 066 */ 067 public void invalidateCaches() throws DirectoryException { 068 cache.invalidateAll(); 069 for (Reference ref : getReferences()) { 070 Directory targetDir = ref.getTargetDirectory(); 071 if (targetDir != null) { 072 targetDir.invalidateDirectoryCache(); 073 } 074 } 075 } 076 077 public DirectoryFieldMapper getFieldMapper() { 078 if (fieldMapper == null) { 079 fieldMapper = new DirectoryFieldMapper(); 080 } 081 return fieldMapper; 082 } 083 084 @Deprecated 085 @Override 086 public Reference getReference(String referenceFieldName) { 087 List<Reference> refs = getReferences(referenceFieldName); 088 if (refs == null || refs.isEmpty()) { 089 return null; 090 } else if (refs.size() == 1) { 091 return refs.get(0); 092 } else { 093 throw new DirectoryException("Unexpected multiple references for " + referenceFieldName + " in directory " 094 + getName()); 095 } 096 } 097 098 @Override 099 public List<Reference> getReferences(String referenceFieldName) { 100 return references.get(referenceFieldName); 101 } 102 103 public boolean isReference(String referenceFieldName) { 104 return references.containsKey(referenceFieldName); 105 } 106 107 public void addReference(Reference reference) { 108 reference.setSourceDirectoryName(getName()); 109 String fieldName = reference.getFieldName(); 110 List<Reference> fieldRefs; 111 if (references.containsKey(fieldName)) { 112 fieldRefs = references.get(fieldName); 113 } else { 114 references.put(fieldName, fieldRefs = new ArrayList<>(1)); 115 } 116 fieldRefs.add(reference); 117 } 118 119 public void addReferences(Reference[] refs) { 120 for (Reference reference : refs) { 121 addReference(reference); 122 } 123 } 124 125 @Override 126 public Collection<Reference> getReferences() { 127 List<Reference> allRefs = new ArrayList<>(2); 128 for (List<Reference> refs : references.values()) { 129 allRefs.addAll(refs); 130 } 131 return allRefs; 132 } 133 134 /** 135 * Helper method to order entries. 136 * 137 * @param entries the list of entries. 138 * @param orderBy an ordered map of field name -> "asc" or "desc". 139 */ 140 public void orderEntries(List<DocumentModel> entries, Map<String, String> orderBy) throws DirectoryException { 141 Collections.sort(entries, new DocumentModelComparator(getSchema(), orderBy)); 142 } 143 144 @Override 145 public DirectoryCache getCache() { 146 return cache; 147 } 148 149 public void removeSession(Session session) { 150 sessionCount.dec(); 151 } 152 153 public void addSession(Session session) { 154 sessionCount.inc(); 155 if (sessionCount.getCount() > sessionMaxCount.getCount()) { 156 sessionMaxCount.inc(); 157 } 158 } 159 160 @Override 161 public void invalidateDirectoryCache() throws DirectoryException { 162 getCache().invalidateAll(); 163 } 164 165 @Override 166 public boolean isMultiTenant() { 167 return false; 168 } 169 170 @Override 171 public void shutdown() { 172 sessionCount.dec(sessionCount.getCount()); 173 sessionMaxCount.dec(sessionMaxCount.getCount()); 174 } 175 176}