1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.chemistry.opencmis.client.bindings.spi.atompub;
20
21 import java.io.Serializable;
22 import java.util.HashSet;
23 import java.util.Map;
24 import java.util.Set;
25
26 import org.apache.chemistry.opencmis.client.bindings.cache.Cache;
27 import org.apache.chemistry.opencmis.client.bindings.cache.impl.CacheImpl;
28 import org.apache.chemistry.opencmis.client.bindings.cache.impl.ContentTypeCacheLevelImpl;
29 import org.apache.chemistry.opencmis.client.bindings.cache.impl.LruCacheLevelImpl;
30 import org.apache.chemistry.opencmis.client.bindings.cache.impl.MapCacheLevelImpl;
31 import org.apache.chemistry.opencmis.client.bindings.spi.BindingSession;
32 import org.apache.chemistry.opencmis.commons.SessionParameter;
33 import org.apache.chemistry.opencmis.commons.SessionParameterDefaults;
34 import org.apache.chemistry.opencmis.commons.impl.Constants;
35 import org.apache.chemistry.opencmis.commons.impl.IOUtils;
36 import org.apache.chemistry.opencmis.commons.impl.UrlBuilder;
37
38
39
40
41 public class LinkCache implements Serializable {
42
43 private static final long serialVersionUID = 1L;
44
45 private static final Set<String> KNOWN_LINKS = new HashSet<String>();
46
47 static {
48 KNOWN_LINKS.add(Constants.REL_ACL);
49 KNOWN_LINKS.add(Constants.REL_DOWN);
50 KNOWN_LINKS.add(Constants.REL_UP);
51 KNOWN_LINKS.add(Constants.REL_FOLDERTREE);
52 KNOWN_LINKS.add(Constants.REL_RELATIONSHIPS);
53 KNOWN_LINKS.add(Constants.REL_SELF);
54 KNOWN_LINKS.add(Constants.REL_ALLOWABLEACTIONS);
55 KNOWN_LINKS.add(Constants.REL_EDITMEDIA);
56 KNOWN_LINKS.add(Constants.REL_POLICIES);
57 KNOWN_LINKS.add(Constants.REL_VERSIONHISTORY);
58 KNOWN_LINKS.add(Constants.REL_WORKINGCOPY);
59 KNOWN_LINKS.add(AtomPubParser.LINK_REL_CONTENT);
60 }
61
62 private final Cache linkCache;
63 private final Cache typeLinkCache;
64 private final Cache collectionLinkCache;
65 private final Cache templateCache;
66 private final Cache repositoryLinkCache;
67
68
69
70
71 public LinkCache(BindingSession session) {
72 int repCount = session.get(SessionParameter.CACHE_SIZE_REPOSITORIES,
73 SessionParameterDefaults.CACHE_SIZE_REPOSITORIES);
74 if (repCount < 1) {
75 repCount = SessionParameterDefaults.CACHE_SIZE_REPOSITORIES;
76 }
77
78 int typeCount = session.get(SessionParameter.CACHE_SIZE_TYPES, SessionParameterDefaults.CACHE_SIZE_TYPES);
79 if (typeCount < 1) {
80 typeCount = SessionParameterDefaults.CACHE_SIZE_TYPES;
81 }
82
83 int objCount = session.get(SessionParameter.CACHE_SIZE_LINKS, SessionParameterDefaults.CACHE_SIZE_LINKS);
84 if (objCount < 1) {
85 objCount = SessionParameterDefaults.CACHE_SIZE_LINKS;
86 }
87
88 linkCache = new CacheImpl("Link Cache");
89 linkCache.initialize(new String[] {
90 MapCacheLevelImpl.class.getName() + " " + MapCacheLevelImpl.CAPACITY + "=" + repCount,
91 LruCacheLevelImpl.class.getName() + " " + LruCacheLevelImpl.MAX_ENTRIES + "=" + objCount,
92 MapCacheLevelImpl.class.getName() + " " + MapCacheLevelImpl.CAPACITY + "=12",
93 ContentTypeCacheLevelImpl.class.getName() + " " + MapCacheLevelImpl.CAPACITY + "=3,"
94 + MapCacheLevelImpl.SINGLE_VALUE + "=true"
95 });
96
97 typeLinkCache = new CacheImpl("Type Link Cache");
98 typeLinkCache.initialize(new String[] {
99 MapCacheLevelImpl.class.getName() + " " + MapCacheLevelImpl.CAPACITY + "=" + repCount,
100 LruCacheLevelImpl.class.getName() + " " + LruCacheLevelImpl.MAX_ENTRIES + "=" + typeCount,
101 MapCacheLevelImpl.class.getName() + " " + MapCacheLevelImpl.CAPACITY + "=12",
102 ContentTypeCacheLevelImpl.class.getName() + " " + MapCacheLevelImpl.CAPACITY + "=3,"
103 + MapCacheLevelImpl.SINGLE_VALUE + "=true"
104 });
105
106 collectionLinkCache = new CacheImpl("Collection Link Cache");
107 collectionLinkCache.initialize(new String[] {
108 MapCacheLevelImpl.class.getName() + " " + MapCacheLevelImpl.CAPACITY + "=" + repCount,
109 MapCacheLevelImpl.class.getName() + " " + MapCacheLevelImpl.CAPACITY + "=8"
110 });
111
112 templateCache = new CacheImpl("URI Template Cache");
113 templateCache.initialize(new String[] {
114 MapCacheLevelImpl.class.getName() + " " + MapCacheLevelImpl.CAPACITY + "=" + repCount,
115 MapCacheLevelImpl.class.getName() + " " + MapCacheLevelImpl.CAPACITY + "=6"
116 });
117
118 repositoryLinkCache = new CacheImpl("Repository Link Cache");
119 repositoryLinkCache.initialize(new String[] {
120 MapCacheLevelImpl.class.getName() + " " + MapCacheLevelImpl.CAPACITY + "=" + repCount,
121 MapCacheLevelImpl.class.getName() + " " + MapCacheLevelImpl.CAPACITY + "=6"
122 });
123 }
124
125
126
127
128 public void addLink(String repositoryId, String id, String rel, String type, String link) {
129 if (KNOWN_LINKS.contains(rel)) {
130 linkCache.put(link, repositoryId, id, rel, type);
131 } else if (Constants.REL_ALTERNATE.equals(rel)) {
132
133 String streamId = extractStreamId(link);
134 if (streamId != null) {
135 linkCache.put(link, repositoryId, id, rel, streamId);
136 }
137 }
138 }
139
140
141
142
143
144 protected String extractStreamId(String link) {
145 int i = link.lastIndexOf('?');
146 if (i > 0) {
147 String[] params = link.substring(i + 1).split("&");
148 for (String param : params) {
149 String[] parts = param.split("=", 2);
150 if (parts[0].equals(Constants.PARAM_STREAM_ID) && parts.length == 2) {
151 return parts[1];
152 }
153 }
154 }
155 return null;
156 }
157
158
159
160
161 public void removeLinks(String repositoryId, String id) {
162 linkCache.remove(repositoryId, id);
163 }
164
165
166
167
168 public String getLink(String repositoryId, String id, String rel, String type) {
169 return (String) linkCache.get(repositoryId, id, rel, type);
170 }
171
172
173
174
175 public String getLink(String repositoryId, String id, String rel) {
176 return getLink(repositoryId, id, rel, null);
177 }
178
179
180
181
182 public int checkLink(String repositoryId, String id, String rel, String type) {
183 return linkCache.check(repositoryId, id, rel, type);
184 }
185
186
187
188
189 public void lockLinks() {
190 linkCache.writeLock();
191 }
192
193
194
195
196 public void unlockLinks() {
197 linkCache.writeUnlock();
198 }
199
200
201
202
203 public void addTypeLink(String repositoryId, String id, String rel, String type, String link) {
204 if (KNOWN_LINKS.contains(rel)) {
205 typeLinkCache.put(link, repositoryId, id, rel, type);
206 }
207 }
208
209
210
211
212 public void removeTypeLinks(String repositoryId, String id) {
213 typeLinkCache.remove(repositoryId, id);
214 }
215
216
217
218
219 public String getTypeLink(String repositoryId, String id, String rel, String type) {
220 return (String) typeLinkCache.get(repositoryId, id, rel, type);
221 }
222
223
224
225
226 public void lockTypeLinks() {
227 typeLinkCache.writeLock();
228 }
229
230
231
232
233 public void unlockTypeLinks() {
234 typeLinkCache.writeUnlock();
235 }
236
237
238
239
240 public void addCollection(String repositoryId, String collection, String link) {
241 collectionLinkCache.put(link, repositoryId, collection);
242 }
243
244
245
246
247 public String getCollection(String repositoryId, String collection) {
248 return (String) collectionLinkCache.get(repositoryId, collection);
249 }
250
251
252
253
254 public void addTemplate(String repositoryId, String type, String link) {
255 templateCache.put(link, repositoryId, type);
256 }
257
258
259
260
261
262 public String getTemplateLink(String repositoryId, String type, Map<String, Object> parameters) {
263 String template = (String) templateCache.get(repositoryId, type);
264 if (template == null) {
265 return null;
266 }
267
268 StringBuilder result = new StringBuilder(128);
269 StringBuilder param = new StringBuilder(32);
270
271 boolean paramMode = false;
272 for (int i = 0; i < template.length(); i++) {
273 char c = template.charAt(i);
274
275 if (paramMode) {
276 if (c == '}') {
277 paramMode = false;
278
279 String paramValue = UrlBuilder.normalizeParameter(parameters.get(param.toString()));
280 if (paramValue != null) {
281 result.append(IOUtils.encodeURL(paramValue));
282 }
283
284 param.setLength(0);
285 } else {
286 param.append(c);
287 }
288 } else {
289 if (c == '{') {
290 paramMode = true;
291 } else {
292 result.append(c);
293 }
294 }
295 }
296
297 return result.toString();
298 }
299
300
301
302
303 public void addRepositoryLink(String repositoryId, String rel, String link) {
304 repositoryLinkCache.put(link, repositoryId, rel);
305 }
306
307
308
309
310 public String getRepositoryLink(String repositoryId, String rel) {
311 return (String) repositoryLinkCache.get(repositoryId, rel);
312 }
313
314
315
316
317 public void clearRepository(String repositoryId) {
318 linkCache.remove(repositoryId);
319 typeLinkCache.remove(repositoryId);
320 collectionLinkCache.remove(repositoryId);
321 templateCache.remove(repositoryId);
322 repositoryLinkCache.remove(repositoryId);
323 }
324
325
326
327
328
329
330 @Override
331 public String toString() {
332 return "Link Cache [link cache=" + linkCache + ", type link cache=" + typeLinkCache
333 + ", collection link cache=" + collectionLinkCache + ", repository link cache=" + repositoryLinkCache
334 + ", template cache=" + templateCache + "]";
335 }
336 }