/* * Licensed to Jasig under one or more contributor license * agreements. See the NOTICE file distributed with this work * for additional information regarding copyright ownership. * Jasig licenses this file to you under the Apache License, * Version 2.0 (the "License"); you may not use this file * except in compliance with the License. You may obtain a * copy of the License at the following location: * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.jasig.cas.ticket; import javax.persistence.Column; import javax.persistence.Id; import javax.persistence.Lob; import javax.persistence.ManyToOne; import javax.persistence.MappedSuperclass; import org.springframework.util.Assert; /** * Abstract implementation of a ticket that handles all ticket state for * policies. Also incorporates properties common among all tickets. As this is * an abstract class, it cannnot be instanciated. It is recommended that * implementations of the Ticket interface extend the AbstractTicket as it * handles common functionality amongst different ticket types (such as state * updating). * * AbstractTicket does not provide a protected Logger instance to * avoid instantiating many such Loggers at runtime (there will be many instances * of subclasses of AbstractTicket in a typical running CAS server). Instead * subclasses should use static Logger instances. * * @author Scott Battaglia * @since 3.0 */ @MappedSuperclass public abstract class AbstractTicket implements Ticket, TicketState { private static final long serialVersionUID = -8506442397878267555L; /** The ExpirationPolicy this ticket will be following. */ @Lob @Column(name="EXPIRATION_POLICY", nullable=false) private ExpirationPolicy expirationPolicy; /** The unique identifier for this ticket. */ @Id @Column(name="ID", nullable=false) private String id; /** The TicketGrantingTicket this is associated with. */ @ManyToOne(targetEntity=TicketGrantingTicketImpl.class) private TicketGrantingTicket ticketGrantingTicket; /** The last time this ticket was used. */ @Column(name="LAST_TIME_USED") private long lastTimeUsed; /** The previous last time this ticket was used. */ @Column(name="PREVIOUS_LAST_TIME_USED") private long previousLastTimeUsed; /** The time the ticket was created. */ @Column(name="CREATION_TIME") private long creationTime; /** The number of times this was used. */ @Column(name="NUMBER_OF_TIMES_USED") private int countOfUses; protected AbstractTicket() { // nothing to do } /** * Constructs a new Ticket with a unique id, a possible parent Ticket (can * be null) and a specified Expiration Policy. * * @param id the unique identifier for the ticket * @param ticket the parent TicketGrantingTicket * @param expirationPolicy the expiration policy for the ticket. * @throws IllegalArgumentException if the id or expiration policy is null. */ public AbstractTicket(final String id, final TicketGrantingTicket ticket, final ExpirationPolicy expirationPolicy) { Assert.notNull(expirationPolicy, "expirationPolicy cannot be null"); Assert.notNull(id, "id cannot be null"); this.id = id; this.creationTime = System.currentTimeMillis(); this.lastTimeUsed = System.currentTimeMillis(); this.expirationPolicy = expirationPolicy; this.ticketGrantingTicket = ticket; } public final String getId() { return this.id; } /** * Records the <i>previous</i> last time this ticket was used as well as * the last usage time. The ticket usage count is also incremented. * * <p>Tickets themselves are solely responsible to maintain their state. The * determination of ticket usage is left up to the implementation and * the specific ticket type. * * @see ExpirationPolicy */ protected final void updateState() { this.previousLastTimeUsed = this.lastTimeUsed; this.lastTimeUsed = System.currentTimeMillis(); this.countOfUses++; } public final int getCountOfUses() { return this.countOfUses; } public final long getCreationTime() { return this.creationTime; } public final TicketGrantingTicket getGrantingTicket() { return this.ticketGrantingTicket; } public final long getLastTimeUsed() { return this.lastTimeUsed; } public final long getPreviousTimeUsed() { return this.previousLastTimeUsed; } public final boolean isExpired() { return this.expirationPolicy.isExpired(this) || (getGrantingTicket() != null && getGrantingTicket().isExpired()) || isExpiredInternal(); } protected boolean isExpiredInternal() { return false; } public final int hashCode() { return this.getId().hashCode(); } public final String toString() { return this.getId(); } }