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 *     Gagnavarslan ehf
018 */
019package org.nuxeo.ecm.webdav.backend;
020
021import java.util.HashMap;
022import java.util.Map;
023import java.util.concurrent.ConcurrentHashMap;
024
025import org.nuxeo.ecm.core.api.CoreSession;
026import org.nuxeo.ecm.core.api.DocumentModel;
027import org.nuxeo.ecm.core.api.DocumentNotFoundException;
028import org.nuxeo.ecm.core.api.IdRef;
029
030public class PathCache {
031
032    private static final long FOLDER_LIFE_TIME = 30 * 60 * 1000;
033
034    private static final long FILE_LIFE_TIME = 1 * 60 * 1000;
035
036    private int maxSize;
037
038    private Map<String, Value> pathToUuidCache = new ConcurrentHashMap<String, Value>();
039
040    private CoreSession session;
041
042    public PathCache(CoreSession session, int maxSize) {
043        this.session = session;
044        this.maxSize = maxSize;
045    }
046
047    public void put(String path, DocumentModel model) {
048        if (model == null) {
049            return;
050        }
051        if (pathToUuidCache.size() >= maxSize) {
052            clean();
053        }
054        pathToUuidCache.put(path, new Value(System.currentTimeMillis()
055                + (model.isFolder() ? FOLDER_LIFE_TIME : FILE_LIFE_TIME), model.getId()));
056    }
057
058    public DocumentModel get(String path) {
059        Value value = pathToUuidCache.get(path);
060        if (value == null) {
061            return null;
062        }
063
064        if (value.getExpiredTime() < System.currentTimeMillis()) {
065            pathToUuidCache.remove(path);
066            return null;
067        }
068        String uuid = value.getValue();
069        DocumentModel model = null;
070        try {
071            model = session.getDocument(new IdRef(uuid));
072        } catch (DocumentNotFoundException e) {
073            // do nothing
074        }
075        if (model == null) {
076            pathToUuidCache.remove(path);
077        }
078
079        return model;
080    }
081
082    public void remove(String path) {
083        Map<String, Value> cacheCopy = new HashMap<String, Value>(pathToUuidCache);
084        for (String key : cacheCopy.keySet()) {
085            if (key.startsWith(path)) {
086                pathToUuidCache.remove(key);
087            }
088        }
089    }
090
091    private int clean() {
092        Map<String, Value> tmpMap = new HashMap<String, Value>(pathToUuidCache);
093        for (String key : tmpMap.keySet()) {
094            if ((pathToUuidCache.get(key).getExpiredTime()) < System.currentTimeMillis()) {
095                remove(key);
096            }
097        }
098        return pathToUuidCache.size();
099    }
100
101    private class Value {
102        private long expiredTime;
103
104        private String value;
105
106        private Value(long expiredTime, String value) {
107            this.expiredTime = expiredTime;
108            this.value = value;
109        }
110
111        public long getExpiredTime() {
112            return expiredTime;
113        }
114
115        @SuppressWarnings("unused")
116        public void setExpiredTime(long expiredTime) {
117            this.expiredTime = expiredTime;
118        }
119
120        public String getValue() {
121            return value;
122        }
123
124        @SuppressWarnings("unused")
125        public void setValue(String value) {
126            this.value = value;
127        }
128    }
129
130}