001/* 002 * acme4j - Java ACME client 003 * 004 * Copyright (C) 2016 Richard "Shred" Körber 005 * http://acme4j.shredzone.org 006 * 007 * Licensed under the Apache License, Version 2.0 (the "License"); 008 * you may not use this file except in compliance with the License. 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. 013 */ 014package org.shredzone.acme4j; 015 016import java.io.Serial; 017import java.io.Serializable; 018import java.net.URL; 019import java.util.Objects; 020 021import edu.umd.cs.findbugs.annotations.Nullable; 022 023/** 024 * This is the root class of all ACME resources (like accounts, orders, certificates). 025 * Every resource is identified by its location URL. 026 * <p> 027 * This class also takes care for proper serialization and de-serialization of the 028 * resource. After de-serialization, the resource must be bound to a {@link Login} again, 029 * using {@link #rebind(Login)}. 030 */ 031public abstract class AcmeResource implements Serializable { 032 @Serial 033 private static final long serialVersionUID = -7930580802257379731L; 034 035 private transient @Nullable Login login; 036 private final URL location; 037 038 /** 039 * Create a new {@link AcmeResource}. 040 * 041 * @param login 042 * {@link Login} the resource is bound with 043 * @param location 044 * Location {@link URL} of this resource 045 */ 046 protected AcmeResource(Login login, URL location) { 047 this.location = Objects.requireNonNull(location, "location"); 048 rebind(login); 049 } 050 051 /** 052 * Gets the {@link Login} this resource is bound with. 053 */ 054 protected Login getLogin() { 055 if (login == null) { 056 throw new IllegalStateException("Use rebind() for binding this object to a login."); 057 } 058 return login; 059 } 060 061 /** 062 * Gets the {@link Session} this resource is bound with. 063 */ 064 protected Session getSession() { 065 return getLogin().getSession(); 066 } 067 068 /** 069 * Rebinds this resource to a {@link Login}. 070 * <p> 071 * Logins are not serialized, because they contain volatile session data and also a 072 * private key. After de-serialization of an {@link AcmeResource}, use this method to 073 * rebind it to a {@link Login}. 074 * 075 * @param login 076 * {@link Login} to bind this resource to 077 */ 078 public void rebind(Login login) { 079 if (this.login != null) { 080 throw new IllegalStateException("Resource is already bound to a login"); 081 } 082 this.login = Objects.requireNonNull(login, "login"); 083 } 084 085 /** 086 * Gets the resource's location. 087 */ 088 public URL getLocation() { 089 return location; 090 } 091 092 @Override 093 protected final void finalize() { 094 // CT_CONSTRUCTOR_THROW: Prevents finalizer attack 095 } 096 097}