Statistics
| Branch: | Tag: | Revision:

root / src / org / gss_project / gss / server / webdav / milton / GssMemoryLockManager.java @ 1206:292dec4eae08

History | View | Annotate | Download (4.9 kB)

1
/*
2
 * Copyright 2011 Electronic Business Systems Ltd.
3
 *
4
 * This file is part of GSS.
5
 *
6
 * GSS is free software: you can redistribute it and/or modify
7
 * it under the terms of the GNU General Public License as published by
8
 * the Free Software Foundation, either version 3 of the License, or
9
 * (at your option) any later version.
10
 *
11
 * GSS is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 * GNU General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU General Public License
17
 * along with GSS.  If not, see <http://www.gnu.org/licenses/>.
18
 */
19
package org.gss_project.gss.server.webdav.milton;
20

    
21
import java.util.Date;
22
import java.util.HashMap;
23
import java.util.Map;
24
import java.util.UUID;
25

    
26
import org.slf4j.Logger;
27
import org.slf4j.LoggerFactory;
28

    
29
import com.bradmcevoy.http.LockInfo;
30
import com.bradmcevoy.http.LockResult;
31
import com.bradmcevoy.http.LockTimeout;
32
import com.bradmcevoy.http.LockToken;
33
import com.bradmcevoy.http.LockableResource;
34
import com.bradmcevoy.http.exceptions.NotAuthorizedException;
35
import com.ettrema.http.fs.LockManager;
36

    
37

    
38
/**
39
 * @author kman
40
 *
41
 */
42
public class GssMemoryLockManager implements LockManager {
43

    
44
    private static final Logger log = LoggerFactory.getLogger( GssMemoryLockManager.class );
45
    /**
46
     * maps current locks by the file associated with the resource
47
     */
48
    Map<String, CurrentLock> locksByFile;
49
    Map<String, CurrentLock> locksByToken;
50

    
51
    public GssMemoryLockManager() {
52
        locksByFile = new HashMap<String, CurrentLock>();
53
        locksByToken = new HashMap<String, CurrentLock>();
54
    }
55

    
56
    public synchronized LockResult lock( LockTimeout timeout, LockInfo lockInfo, LockableResource r ) {
57
        GssResource resource = (GssResource) r;
58
        LockToken currentLock = currentLock( resource );
59
        if( currentLock != null ) {
60
            return LockResult.failed( LockResult.FailureReason.ALREADY_LOCKED );
61
        }
62

    
63
        LockToken newToken = new LockToken( UUID.randomUUID().toString(), lockInfo, timeout );
64
        CurrentLock newLock = new CurrentLock( resource.getUniqueId(), newToken, lockInfo.lockedByUser );
65
        locksByFile.put( resource.getUniqueId(), newLock );
66
        locksByToken.put( newToken.tokenId, newLock );
67
        return LockResult.success( newToken );
68
    }
69

    
70
    public synchronized LockResult refresh( String tokenId, LockableResource resource ) {
71
        CurrentLock curLock = locksByToken.get( tokenId );
72
        if( curLock == null ) {
73
            log.debug( "can't refresh because no lock");
74
            return LockResult.failed( LockResult.FailureReason.PRECONDITION_FAILED );
75
        } else {
76
            curLock.token.setFrom( new Date() );
77
            return LockResult.success( curLock.token );
78
        }
79
    }
80

    
81
    public synchronized void unlock( String tokenId, LockableResource r ) throws NotAuthorizedException {
82
            GssResource resource = (GssResource) r;
83
        LockToken lockToken = currentLock( resource );
84
        if( lockToken == null ) {
85
            log.debug( "not locked" );
86
            return;
87
        }
88
        if( lockToken.tokenId.equals( tokenId ) ) {
89
            removeLock( lockToken );
90
        } else {
91
            throw new NotAuthorizedException( resource );
92
        }
93
    }
94

    
95
    private LockToken currentLock( GssResource resource ) {
96
        CurrentLock curLock = locksByFile.get( resource.getUniqueId() );
97
        if( curLock == null ) return null;
98
        LockToken token = curLock.token;
99
        if( token.isExpired() ) {
100
            removeLock( token );
101
            return null;
102
        } else {
103
            return token;
104
        }
105
    }
106

    
107
    private void removeLock( LockToken token ) {
108
        log.debug( "removeLock: " + token.tokenId );
109
        CurrentLock currentLock = locksByToken.get( token.tokenId );
110
        if( currentLock != null ) {
111
            locksByFile.remove( currentLock.file );
112
            locksByToken.remove( currentLock.token.tokenId );
113
        } else {
114
            log.warn( "couldnt find lock: " + token.tokenId );
115
        }
116
    }
117

    
118
    public LockToken getCurrentToken( LockableResource r ) {
119
            GssResource resource = (GssResource) r;
120
        CurrentLock lock = locksByFile.get( resource.getUniqueId() );
121
        if( lock == null ) return null;
122
        LockToken token = new LockToken();
123
        token.info = new LockInfo( LockInfo.LockScope.EXCLUSIVE, LockInfo.LockType.WRITE, lock.lockedByUser, LockInfo.LockDepth.ZERO );
124
        token.info.lockedByUser = lock.lockedByUser;
125
        token.timeout = lock.token.timeout;
126
        token.tokenId = lock.token.tokenId;
127
        return token;
128
    }
129

    
130
    class CurrentLock {
131

    
132
        final String file;
133
        final LockToken token;
134
        final String lockedByUser;
135

    
136
        public CurrentLock( String file, LockToken token, String lockedByUser ) {
137
            this.file = file;
138
            this.token = token;
139
            this.lockedByUser = lockedByUser;
140
        }
141
    }
142

    
143
}