2121import jakarta .servlet .http .HttpServletRequest ;
2222import jakarta .servlet .http .HttpServletResponse ;
2323import org .apache .commons .lang3 .StringUtils ;
24- import org .apache .logging .log4j .LogManager ;
2524import org .apache .logging .log4j .Logger ;
25+ import org .jetbrains .annotations .NotNull ;
2626import org .jetbrains .annotations .Nullable ;
2727import org .json .JSONObject ;
28- import org .jetbrains .annotations .NotNull ;
2928import org .labkey .api .action .ApiResponseWriter .Format ;
3029import org .labkey .api .admin .AdminUrls ;
3130import org .labkey .api .collections .CaseInsensitiveHashMap ;
5655import org .labkey .api .util .PageFlowUtil ;
5756import org .labkey .api .util .Path ;
5857import org .labkey .api .util .URLHelper ;
58+ import org .labkey .api .util .logging .LogHelper ;
5959import org .labkey .api .view .ActionURL ;
6060import org .labkey .api .view .BadRequestException ;
6161import org .labkey .api .view .HttpView ;
@@ -131,7 +131,7 @@ public abstract class SpringActionController implements Controller, HasViewConte
131131
132132 private static final Map <Class <? extends Controller >, ActionDescriptor > _classToDescriptor = new HashMap <>();
133133
134- private static final Logger _log = LogManager .getLogger (SpringActionController .class );
134+ private static final Logger _log = LogHelper .getLogger (SpringActionController .class , "Problems with actions and template" );
135135
136136 public void setActionResolver (ActionResolver actionResolver )
137137 {
@@ -146,7 +146,8 @@ public ActionResolver getActionResolver()
146146 protected static void registerAction (ActionDescriptor ad )
147147 {
148148 ActionDescriptor prev = _classToDescriptor .put (ad .getActionClass (), ad );
149- assert null == prev || prev == ad ;
149+ if (null != prev )
150+ throw new IllegalStateException ("Action class '" + prev .getActionClass () + "' has already registered with a controller" );
150151 }
151152
152153 @ Nullable
@@ -751,16 +752,17 @@ protected void addNavTrail(Controller action, NavTree root)
751752 if (action instanceof NavTrailAction )
752753 {
753754 ((NavTrailAction )action ).addNavTrail (root );
754- assert isValidNavTree (root , action ) : action .getClass ().getName () + " is generating a malformed NavTree" ;
755+ if (!isValidNavTree (root ))
756+ throw new IllegalStateException (action .getClass ().getName () + " is generating a malformed NavTree" );
755757 }
756758 }
757759
758760 // NavTrail renders only the first level children, so flag the NavTree as invalid if any child has children. This
759761 // most likely means that addNavTrail() chained calls to addChild(), which adds nodes that will never render.
760- private boolean isValidNavTree (NavTree tree , Controller action )
762+ private boolean isValidNavTree (NavTree tree )
761763 {
762- return tree .getChildren ().stream () // Very temporary exception for RespondAction. TODO: Remove once 20.7.2 changes are merged to develop.
763- .noneMatch (NavTree ::hasChildren ) || "org.labkey.announcements.AnnouncementsController$RespondAction" . equals ( action . getClass (). getName ()) ;
764+ return tree .getChildren ().stream ()
765+ .noneMatch (NavTree ::hasChildren );
764766 }
765767
766768 protected void beforeAction (Controller action ) throws ServletException
@@ -1229,9 +1231,9 @@ public static void clearActionForThread(Controller c)
12291231 public static void clearActionForThread (Class <?> c )
12301232 {
12311233 ArrayList <Class <?>> list = currentAction .get ();
1232- assert ! list .isEmpty ();
1233- assert list . getLast () == c ;
1234- list . removeLast ( );
1234+ Class <?> last = list .removeLast ();
1235+ if ( last != c )
1236+ throw new IllegalStateException ( "Unexpected last action class: " + last . getName () + " vs. " + c . getName () );
12351237 }
12361238
12371239 @ Nullable
@@ -1247,30 +1249,34 @@ public static void checkForMutatingSql(Supplier<String> mutatingSqlSupplier)
12471249 {
12481250 if (ignoreUpdates .get ())
12491251 return ;
1250- Class <?> c = getActionForThread ();
1251- if (null == c )
1252+ Class <?> actionClass = getActionForThread ();
1253+ if (null == actionClass )
12521254 return ;
12531255
12541256 ViewContext vc = HttpView .currentContext ();
12551257 boolean readonly = false ;
12561258
1257- if (ReadOnlyApiAction .class .isAssignableFrom (c ))
1259+ if (ReadOnlyApiAction .class .isAssignableFrom (actionClass ))
12581260 {
12591261 readonly = true ;
12601262 }
1261- else if (SimpleRedirectAction .class .isAssignableFrom (c ) || SimpleViewAction .class .isAssignableFrom (c ))
1263+ else if (SimpleRedirectAction .class .isAssignableFrom (actionClass ) || SimpleViewAction .class .isAssignableFrom (actionClass ))
12621264 {
12631265 readonly = true ;
12641266 }
1265- else if ( null != vc && "GET" . equals ( vc . getRequest (). getMethod ()))
1267+ else
12661268 {
1267- readonly = true ;
1268- _log .warn ("Action {} accepted GET unexpectedly... might need to update checkForMutatingSql()" , c .getName ());
1269+ if (null != vc && "GET" .equals (vc .getRequest ().getMethod ()))
1270+ {
1271+ readonly = true ;
1272+ if (!FormViewAction .class .isAssignableFrom (actionClass ) && AppProps .getInstance ().isDevMode ())
1273+ _log .warn ("Action {} accepted GET unexpectedly... might need to update checkForMutatingSql()" , actionClass .getName ());
1274+ }
12691275 }
12701276
12711277 if (readonly )
12721278 {
1273- if (c .getName ().contains ("JunitController" ))
1279+ if (actionClass .getName ().contains ("JunitController" ))
12741280 return ;
12751281
12761282 // Checking this late in the game to ensure OptionalFeatureService has been initialized.
@@ -1281,10 +1287,10 @@ else if (null != vc && "GET".equals(vc.getRequest().getMethod()))
12811287 String mutatingSql = mutatingSqlSupplier .get ();
12821288 if (mutatingSql != null )
12831289 {
1284- boolean verbose = _log .isDebugEnabled () || mutatingActionsWarned .add (c .getName ());
1290+ boolean verbose = _log .isDebugEnabled () || mutatingActionsWarned .add (actionClass .getName ());
12851291 String message = "MUTATING SQL executed as part of handling action: " +
12861292 (null == vc ? "" : vc .getRequest ().getMethod ()) + " " +
1287- c .getName () + (verbose ? ("\n " + mutatingSql ) : "" );
1293+ actionClass .getName () + (verbose ? ("\n " + mutatingSql ) : "" );
12881294 throw new IllegalStateException (message );
12891295 }
12901296 }
0 commit comments