/*
* Copyright (C) 2009 eXo Platform SAS.
*
* This is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/
package org.exoplatform.services.jcr.impl.core.lock.cacheable;
import org.exoplatform.services.jcr.impl.Constants;
import java.io.Externalizable;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectOutput;
/**
* Created by The eXo Platform SAS.
*
* @author <a href="mailto:gennady.azarenkov@exoplatform.com">Gennady Azarenkov</a>
* @version $Id: LockData.java 787 2009-11-20 11:36:15Z nzamosenchuk $
*/
public class LockData implements Externalizable
{
/**
* The time of birth. From this time we start count the time of death. death = birthday+TIME_OUT;
*/
private long birthday;
/**
* If isDeep is true then the lock applies to this node and all its descendant nodes; if false,
* the lock applies only to this, the holding node.
*/
private boolean deep;
/**
* A lock token is a string that uniquely identifies a particular lock and acts as a “key”
* allowing a user to alter a locked node. LockData stores only token hash.
*/
private String tokenHash;
/**
* Identifier of locked node.
*/
private String nodeIdentifier;
/**
* The owner of the locked node.
*/
private String owner;
/**
* If isSessionScoped is true then this lock will expire upon the expiration of the current
* session (either through an automatic or explicit Session.logout); if false, this lock does not
* expire until explicitly unlocked or automatically unlocked due to a implementation-specific
* limitation, such as a timeout.
*/
private boolean sessionScoped;
/**
* <B>8.4.9 Timing Out</B> An implementation may unlock any lock at any time due to
* implementation-specific criteria, such as time limits on locks.
*/
private long timeOut;
// Need for Externalizable
public LockData()
{
this.sessionScoped = false;
this.deep = false;
}
/**
* @param nodeIdentifier
* @param lockTokenHash
* @param deep
* @param sessionScoped
* @param owner
* @param timeOut
* is seconds!
*/
public LockData(String nodeIdentifier, String lockTokenHash, boolean deep, boolean sessionScoped, String owner,
long timeOut)
{
this(nodeIdentifier, lockTokenHash, deep, sessionScoped, owner, timeOut, System.currentTimeMillis());
}
/**
* @param nodeIdentifier
* @param lockTokenHash
* @param deep
* @param sessionScoped
* @param owner
* @param timeOut
* is seconds!
* @param birthday
*/
public LockData(String nodeIdentifier, String lockTokenHash, boolean deep, boolean sessionScoped, String owner,
long timeOut, long birthday)
{
this.nodeIdentifier = nodeIdentifier;
this.tokenHash = lockTokenHash;
this.deep = deep;
this.sessionScoped = sessionScoped;
this.owner = owner;
this.timeOut = timeOut;
this.birthday = birthday;
}
/*
* (non-Javadoc)
* @see java.lang.Object#equals(java.lang.Object)
*/
@Override
public boolean equals(Object obj)
{
if (super.equals(obj))
{
return true;
}
if (obj instanceof LockData)
{
return hashCode() == obj.hashCode();
}
return false;
}
/**
* @return the nodeIdentifier
*/
public String getNodeIdentifier()
{
return nodeIdentifier;
}
/**
* @return
*/
public String getOwner()
{
return owner;
}
/**
* @return The time to death in millis
*/
public long getTimeToDeath()
{
return birthday + timeOut - System.currentTimeMillis();
}
public String getTokenHash()
{
return tokenHash;
}
/*
* (non-Javadoc)
* @see java.lang.Object#hashCode()
*/
@Override
public int hashCode()
{
return tokenHash.hashCode();
}
public boolean isDeep()
{
return deep;
}
/**
* @return
*/
public boolean isSessionScoped()
{
return sessionScoped;
}
/**
* @see java.io.Externalizable#readExternal(java.io.ObjectInput)
*/
public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException
{
// read boolean
this.deep = in.readBoolean();
this.sessionScoped = in.readBoolean();
// read long
this.birthday = in.readLong();
this.timeOut = in.readLong();
//read strings
// read uuid
byte[] buf;
buf = new byte[in.readInt()];
in.readFully(buf);
this.nodeIdentifier = new String(buf, Constants.DEFAULT_ENCODING);
// read owner
buf = new byte[in.readInt()];
in.readFully(buf);
this.owner = new String(buf, Constants.DEFAULT_ENCODING);
// read token
buf = new byte[in.readInt()];
in.readFully(buf);
this.tokenHash = new String(buf, Constants.DEFAULT_ENCODING);
}
/**
* @see java.io.Externalizable#writeExternal(java.io.ObjectOutput)
*/
public void writeExternal(ObjectOutput out) throws IOException
{
// write boolean
out.writeBoolean(deep);
out.writeBoolean(sessionScoped);
// write long
out.writeLong(birthday);
out.writeLong(timeOut);
// write string
// node uuid
byte[] ptbuf = nodeIdentifier.getBytes(Constants.DEFAULT_ENCODING);
out.writeInt(ptbuf.length);
out.write(ptbuf);
// node owner
ptbuf = owner.getBytes(Constants.DEFAULT_ENCODING);
out.writeInt(ptbuf.length);
out.write(ptbuf);
// node token
ptbuf = tokenHash.getBytes(Constants.DEFAULT_ENCODING);
out.writeInt(ptbuf.length);
out.write(ptbuf);
}
/**
* @return
*/
public long getTimeOut()
{
return timeOut;
}
public long getBirthDay()
{
return birthday;
}
public void setTimeOut(long timeOut)
{
this.timeOut = timeOut;
}
}