diff --git a/xmppserver/src/main/java/org/jivesoftware/openfire/muc/HistoryStrategy.java b/xmppserver/src/main/java/org/jivesoftware/openfire/muc/HistoryStrategy.java index 19afe906eb..04667df534 100644 --- a/xmppserver/src/main/java/org/jivesoftware/openfire/muc/HistoryStrategy.java +++ b/xmppserver/src/main/java/org/jivesoftware/openfire/muc/HistoryStrategy.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004-2008 Jive Software, 2016-2025 Ignite Realtime Foundation. All rights reserved. + * Copyright (C) 2004-2008 Jive Software, 2016-2026 Ignite Realtime Foundation. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -124,7 +124,7 @@ public HistoryStrategy(JID roomJID, HistoryStrategy parentStrategy) { maxNumber = DEFAULT_MAX_NUMBER; } else { - type = Type.defaulType; + type = Type.defaultType; maxNumber = parent.getMaxNumber(); } } @@ -205,16 +205,9 @@ public void addMessage(@Nonnull final Message... packets) } // get the conditions based on default or not - final Type strategyType; - final int strategyMaxNumber; - if (type == Type.defaulType && parent != null) { - strategyType = parent.getType(); - strategyMaxNumber = parent.getMaxNumber(); - } - else { - strategyType = type; - strategyMaxNumber = maxNumber; - } + final HistoryStrategy effective = resolveEffective(); + final Type strategyType = effective.getType(); + final int strategyMaxNumber = effective.getMaxNumber(); final Lock lock = MUC_HISTORY_CACHE.getLock(roomJID); lock.lock(); @@ -238,11 +231,7 @@ public void addMessage(@Nonnull final Message... packets) } boolean isHistoryEnabled() { - Type strategyType = type; - if (type == Type.defaulType && parent != null) { - strategyType = parent.getType(); - } - return strategyType != HistoryStrategy.Type.none; + return resolveEffective().getType() != Type.none; } /** @@ -321,6 +310,21 @@ public void purge() } } + /** + * Resolves this strategy to the one whose settings are actually in effect: if this strategy's type is + * {@link Type#defaultType}, walks up the parent chain until a strategy with a concrete type (or no parent) is found. + * Returns this instance if its type is not defaultType, or if it has no parent to defer to. + * + * @return The strategy instance whose type/maxNumber values should be treated as authoritative. + */ + HistoryStrategy resolveEffective() { + HistoryStrategy strategy = this; + while (strategy.type == Type.defaultType && strategy.parent != null) { + strategy = strategy.parent; + } + return strategy; + } + @Override public void writeExternal(ObjectOutput out) throws IOException { ExternalizableUtil.getInstance().writeSerializable(out, type); @@ -383,7 +387,7 @@ public void readExternal(ObjectInput in) throws IOException, ClassNotFoundExcept * Strategy type. */ public enum Type { - defaulType, none, all, number; + defaultType, none, all, number; } /** @@ -400,7 +404,7 @@ public void setTypeFromString(String typeName) { } catch (Exception e) { if (parent != null) { - type = Type.defaulType; + type = Type.defaultType; } else { type = Type.number; diff --git a/xmppserver/src/main/java/org/jivesoftware/openfire/muc/MUCRoomHistory.java b/xmppserver/src/main/java/org/jivesoftware/openfire/muc/MUCRoomHistory.java index 19b8e7af87..92ee7a3c8f 100644 --- a/xmppserver/src/main/java/org/jivesoftware/openfire/muc/MUCRoomHistory.java +++ b/xmppserver/src/main/java/org/jivesoftware/openfire/muc/MUCRoomHistory.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004-2008 Jive Software, 2016-2025 Ignite Realtime Foundation. All rights reserved. + * Copyright (C) 2004-2008 Jive Software, 2016-2026 Ignite Realtime Foundation. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -324,8 +324,9 @@ public boolean isSubjectChangeRequest(Message message) { * @return The maximum number of historic messages to keep for this room, or -1. */ public int getMaxMessages() { - return switch (historyStrategy.getType()) { - case number -> historyStrategy.getMaxNumber(); + final HistoryStrategy effective = historyStrategy.resolveEffective(); + return switch (effective.getType()) { + case number -> effective.getMaxNumber(); case none -> 0; default -> -1; };