001package gudusoft.gsqlparser.runtime; 002 003/** 004 * Thrown when an entitlement-gated build is used without a valid entitlement. 005 * 006 * <p><b>This build fails explicitly rather than returning a wrong answer.</b> 007 * An earlier design silently deleted a statement from every parse, so an 008 * unlicensed user got plausible but incomplete results. That is worse than a 009 * refusal in every direction that matters: it is indistinguishable from a 010 * parser bug, it corrupts downstream lineage and impact analysis without 011 * anyone noticing, and it costs the vendor the support calls too. Supportability 012 * wins over covertness.</p> 013 * 014 * <p>Extends {@link IllegalStateException} so existing callers that already 015 * handle unchecked failures from {@code parse()} keep working.</p> 016 * 017 * @see GspRuntime#activate(byte[]) 018 */ 019public class GspNotActivatedException extends IllegalStateException { 020 021 private static final long serialVersionUID = 1L; 022 023 private final GspActivation activation; 024 025 GspNotActivatedException(GspActivation activation) { 026 super("GSP is not activated: this build requires a signed entitlement. " 027 + "reason=" + activation.reasonCode() 028 + " audit=" + activation.auditId() 029 + ". Call GspRuntime.activate(byte[]) with a valid entitlement " 030 + "before parsing."); 031 this.activation = activation; 032 } 033 034 /** The activation state that caused the refusal, for logging and support. */ 035 public GspActivation getActivation() { 036 return activation; 037 } 038 039 /** Stable machine-readable reason, e.g. {@code EXPIRED}, {@code MISSING}. */ 040 public String reasonCode() { 041 return activation.reasonCode(); 042 } 043 044 /** Correlates this refusal with the GSP_ENTITLEMENT_REFUSED log line. */ 045 public String auditId() { 046 return activation.auditId(); 047 } 048}