package org.apereo.cas.ticket; import com.fasterxml.jackson.core.PrettyPrinter; import com.fasterxml.jackson.core.util.MinimalPrettyPrinter; import com.google.common.base.Throwables; import org.apache.commons.lang3.StringUtils; import org.apereo.cas.ticket.proxy.ProxyGrantingTicket; import org.apereo.cas.ticket.proxy.ProxyTicket; import org.apereo.cas.util.serialization.AbstractJacksonBackedStringSerializer; import org.apereo.cas.util.serialization.StringSerializer; import java.io.StringWriter; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; /** * This is {@link BaseTicketSerializers} * that attempts to serialize ticket objects. * * @author Misagh Moayyed * @since 5.1.0 */ public abstract class BaseTicketSerializers { private static final Map<String, Class> TICKET_TYPE_CACHE = new ConcurrentHashMap<>(); private static final PrettyPrinter MINIMAL_PRETTY_PRINTER = new MinimalPrettyPrinter(); /** * Gets proxy granting ticket serializer. * * @return the proxy granting ticket serializer */ public static StringSerializer<ProxyGrantingTicket> getProxyGrantingTicketSerializer() { return new AbstractJacksonBackedStringSerializer<ProxyGrantingTicket>(MINIMAL_PRETTY_PRINTER) { private static final long serialVersionUID = 7089208351327601379L; @Override protected Class<ProxyGrantingTicket> getTypeToSerialize() { return ProxyGrantingTicket.class; } }; } /** * Gets proxy ticket serializer. * * @return the proxy ticket serializer */ public static StringSerializer<ProxyTicket> getProxyTicketSerializer() { return new AbstractJacksonBackedStringSerializer<ProxyTicket>(MINIMAL_PRETTY_PRINTER) { private static final long serialVersionUID = -6343596853082798477L; @Override protected Class<ProxyTicket> getTypeToSerialize() { return ProxyTicket.class; } }; } /** * Gets ticket granting ticket serializer. * * @return the ticket granting ticket serializer */ public static StringSerializer<TicketGrantingTicket> getTicketGrantingTicketSerializer() { return new AbstractJacksonBackedStringSerializer<TicketGrantingTicket>(MINIMAL_PRETTY_PRINTER) { private static final long serialVersionUID = 1527874389457723545L; @Override protected Class<TicketGrantingTicket> getTypeToSerialize() { return TicketGrantingTicket.class; } }; } /** * Gets service ticket serializer. * * @return the service ticket serializer */ public static StringSerializer<ServiceTicket> getServiceTicketSerializer() { return new AbstractJacksonBackedStringSerializer<ServiceTicket>(MINIMAL_PRETTY_PRINTER) { private static final long serialVersionUID = 8959617299162115085L; @Override protected Class<ServiceTicket> getTypeToSerialize() { return ServiceTicket.class; } }; } /** * Serialize ticket. * * @param ticket the ticket * @return the string */ public static String serializeTicket(final Ticket ticket) { final StringWriter writer = new StringWriter(); if (ticket instanceof TicketGrantingTicket) { getTicketGrantingTicketSerializer().to(writer, TicketGrantingTicket.class.cast(ticket)); } else if (ticket instanceof ServiceTicket) { getServiceTicketSerializer().to(writer, ServiceTicket.class.cast(ticket)); } return writer.toString(); } /** * Deserialize ticket. * * @param <T> the type parameter * @param ticketContent the ticket id * @param type the type * @return the ticket instance. */ public static <T extends Ticket> T deserializeTicket(final String ticketContent, final String type) { if (StringUtils.isBlank(type)) { throw new InvalidTicketException("Invalid ticket type [blank] specified"); } try { final Class<T> clazz; if (TICKET_TYPE_CACHE.containsKey(type)) { clazz = TICKET_TYPE_CACHE.get(type); } else { clazz = (Class<T>) Class.forName(type); TICKET_TYPE_CACHE.put(type, clazz); } return deserializeTicket(ticketContent, clazz); } catch (final Exception e) { throw Throwables.propagate(e); } } /** * Deserialize ticket. * * @param <T> the type parameter * @param ticketContent the ticket id * @param clazz the clazz * @return the ticket instance */ public static <T extends Ticket> T deserializeTicket(final String ticketContent, final Class<T> clazz) { Ticket ticket = null; if (TicketGrantingTicket.class.isAssignableFrom(clazz)) { ticket = getTicketGrantingTicketSerializer().from(ticketContent); } else if (ServiceTicket.class.isAssignableFrom(clazz)) { ticket = getServiceTicketSerializer().from(ticketContent); } if (ticket == null) { throw new InvalidTicketException(clazz.getName()); } if (!clazz.isAssignableFrom(ticket.getClass())) { throw new ClassCastException("Ticket [" + ticket.getId() + " is of type " + ticket.getClass() + " when we were expecting " + clazz); } return (T) ticket; } }