001    /*
002     * Cumulus4j - Securing your data in the cloud - http://cumulus4j.org
003     * Copyright (C) 2011 NightLabs Consulting GmbH
004     *
005     * This program is free software: you can redistribute it and/or modify
006     * it under the terms of the GNU Affero General Public License as
007     * published by the Free Software Foundation, either version 3 of the
008     * License, or (at your option) any later version.
009     *
010     * This program is distributed in the hope that it will be useful,
011     * but WITHOUT ANY WARRANTY; without even the implied warranty of
012     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
013     * GNU Affero General Public License for more details.
014     *
015     * You should have received a copy of the GNU Affero General Public License
016     * along with this program.  If not, see <http://www.gnu.org/licenses/>.
017     */
018    package org.cumulus4j.store.crypto;
019    
020    import java.util.Date;
021    
022    import org.slf4j.Logger;
023    import org.slf4j.LoggerFactory;
024    
025    /**
026     * Abstract base-class for implementing {@link CryptoSession}s.
027     *
028     * @author Marco หงุ่ยตระกูล-Schulze - marco at nightlabs dot de
029     */
030    public abstract class AbstractCryptoSession implements CryptoSession
031    {
032            private static final Logger logger = LoggerFactory.getLogger(AbstractCryptoSession.class);
033    
034            private Date creationTimestamp = new Date();
035            private volatile Date lastUsageTimestamp = creationTimestamp;
036            private CryptoManager cryptoManager;
037            private String cryptoSessionID;
038    
039            private volatile boolean closed;
040    
041            @Override
042            public CryptoManager getCryptoManager() {
043                    return cryptoManager;
044            }
045    
046            @Override
047            public void setCryptoManager(CryptoManager cryptoManager)
048            {
049                    if (cryptoManager == null)
050                            throw new IllegalArgumentException("cryptoManager == null");
051    
052                    if (cryptoManager == this.cryptoManager)
053                            return;
054    
055                    if (this.cryptoManager != null)
056                            throw new IllegalStateException("this.cryptoManager already assigned! Cannot modify!");
057    
058                    this.cryptoManager = cryptoManager;
059            }
060    
061            @Override
062            public String getCryptoSessionID()
063            {
064                    return cryptoSessionID;
065            }
066    
067            @Override
068            public void setCryptoSessionID(String cryptoSessionID)
069            {
070                    if (cryptoSessionID == null)
071                            throw new IllegalArgumentException("cryptoSessionID == null");
072    
073                    if (cryptoSessionID.equals(this.cryptoSessionID))
074                            return;
075    
076                    if (this.cryptoSessionID != null)
077                            throw new IllegalStateException("this.cryptoSessionID already assigned! Cannot modify!");
078    
079                    this.cryptoSessionID = cryptoSessionID;
080                    logger.trace("setCryptoSessionID: cryptoSessionID={}", cryptoSessionID);
081            }
082    
083            @Override
084            public Date getCreationTimestamp()
085            {
086                    return creationTimestamp;
087            }
088    
089            @Override
090            public Date getLastUsageTimestamp() {
091                    return lastUsageTimestamp;
092            }
093    
094            @Override
095            public void updateLastUsageTimestamp() {
096                    lastUsageTimestamp = new Date();
097            }
098    
099            /**
100             * {@inheritDoc}
101             * <p>
102             * Implementors should use {@link #assertNotClosed()} in their subclasses to check
103             * whether the operation is still allowed.
104             * </p>
105             */
106            @Override
107            public boolean isClosed() {
108                    return closed;
109            }
110    
111            /**
112             * Throws an {@link IllegalStateException}, if this session is already closed.
113             */
114            protected void assertNotClosed()
115            {
116                    if (isClosed())
117                            throw new IllegalStateException("This session (cryptoSessionID=\"" + cryptoSessionID + "\") is already closed!");
118            }
119    
120            /**
121             * {@inheritDoc}
122             * <p>
123             * When overriding this method, you should first call <code>super.close();</code> and
124             * then perform your own closing operations.
125             * </p>
126             */
127            @Override
128            public void close() {
129                    logger.trace("close: cryptoSessionID={}", cryptoSessionID);
130                    closed = true;
131                    cryptoManager.onCloseCryptoSession(this);
132            }
133    }