/* * 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; } }