21
21
import aQute .bnd .annotation .spi .ServiceConsumer ;
22
22
import java .lang .ref .WeakReference ;
23
23
import java .util .ArrayList ;
24
- import java .util .Arrays ;
25
24
import java .util .Collections ;
26
25
import java .util .HashSet ;
27
26
import java .util .List ;
91
90
@ ServiceConsumer (value = ScriptManagerFactory .class , cardinality = Cardinality .SINGLE , resolution = Resolution .OPTIONAL )
92
91
public abstract class AbstractConfiguration extends AbstractFilterable implements Configuration {
93
92
94
- private static final ConfigurationExtension [] EMPTY_EXTENSIONS = new ConfigurationExtension [0 ];
93
+ private static final List <String > EXPECTED_ELEMENTS =
94
+ List .of ("\" Appenders\" " , "\" Loggers\" " , "\" Properties\" " , "\" Scripts\" " , "\" CustomLevels\" " );
95
95
96
96
/**
97
97
* The instance factory for this configuration. This may be a child factory to a LoggerContext
@@ -159,7 +159,7 @@ public abstract class AbstractConfiguration extends AbstractFilterable implement
159
159
private final WeakReference <LoggerContext > loggerContext ;
160
160
private final PropertyEnvironment contextProperties ;
161
161
private final Lock configLock = new ReentrantLock ();
162
- private ConfigurationExtension [] extensions = EMPTY_EXTENSIONS ;
162
+ private final List < ConfigurationExtension > extensions = new CopyOnWriteArrayList <>() ;
163
163
164
164
/**
165
165
* Constructor.
@@ -659,7 +659,7 @@ protected void doConfigure() {
659
659
if (!hasProperties ) {
660
660
final Map <String , String > map = this .getComponent (CONTEXT_PROPERTIES );
661
661
final StrLookup lookup = map == null ? null : new PropertiesLookup (map );
662
- Interpolator interpolator = interpolatorFactory .newInterpolator (lookup );
662
+ final Interpolator interpolator = interpolatorFactory .newInterpolator (lookup );
663
663
instanceFactory .injectMembers (interpolator );
664
664
runtimeStrSubstitutor .setVariableResolver (interpolator );
665
665
configurationStrSubstitutor .setVariableResolver (interpolator );
@@ -676,6 +676,10 @@ protected void doConfigure() {
676
676
}
677
677
createConfiguration (child , null );
678
678
if (child .getObject () == null ) {
679
+ LOGGER .warn (
680
+ "Configuration element \" {}\" is ignored: try nesting it inside one of: {}." ,
681
+ child .getName (),
682
+ EXPECTED_ELEMENTS );
679
683
continue ;
680
684
}
681
685
if ("Scripts" .equalsIgnoreCase (child .getName ())) {
@@ -686,40 +690,28 @@ protected void doConfigure() {
686
690
appenders = child .getObject ();
687
691
} else if (child .isInstanceOf (Filter .class )) {
688
692
addFilter (child .getObject (Filter .class ));
689
- } else if ("Loggers" . equalsIgnoreCase ( child .getName () )) {
690
- final Loggers l = child .getObject ();
693
+ } else if (child .isInstanceOf ( Loggers . class )) {
694
+ final Loggers l = child .getObject (Loggers . class );
691
695
loggerConfigs = l .getMap ();
692
696
setLoggers = true ;
693
697
if (l .getRoot () != null ) {
694
698
root = l .getRoot ();
695
699
setRoot = true ;
696
700
}
697
- } else if ("CustomLevels" .equalsIgnoreCase (child .getName ())) {
698
- final CustomLevels levels = child .getObject (CustomLevels .class );
699
- if (levels == null ) {
700
- LOGGER .error ("Unable to load CustomLevels plugin" );
701
- } else {
702
- customLevels = levels .getCustomLevels ();
703
- }
701
+ } else if (child .isInstanceOf (CustomLevels .class )) {
702
+ customLevels = child .getObject (CustomLevels .class ).getCustomLevels ();
704
703
} else if (child .isInstanceOf (CustomLevelConfig .class )) {
705
704
final List <CustomLevelConfig > copy = new ArrayList <>(customLevels );
706
705
copy .add (child .getObject (CustomLevelConfig .class ));
707
706
customLevels = copy ;
708
707
} else if (child .isInstanceOf (ConfigurationExtension .class )) {
709
- final ConfigurationExtension extension = child .getObject (ConfigurationExtension .class );
710
- if (extension == null ) {
711
- LOGGER .error ("Unable to load configuration extension {}." , child .getName ());
712
- } else {
713
- addExtension (child .getObject ());
714
- }
708
+ addExtension (child .getObject (ConfigurationExtension .class ));
715
709
} else {
716
- final List <String > expected = Arrays .asList (
717
- "\" Appenders\" " , "\" Loggers\" " , "\" Properties\" " , "\" Scripts\" " , "\" CustomLevels\" " );
718
710
LOGGER .error (
719
711
"Unknown object \" {}\" of type {} is ignored: try nesting it inside one of: {}." ,
720
712
child .getName (),
721
713
child .getObject ().getClass ().getName (),
722
- expected );
714
+ EXPECTED_ELEMENTS );
723
715
}
724
716
}
725
717
@@ -1154,19 +1146,28 @@ public void setNanoClock(final NanoClock nanoClock) {
1154
1146
}
1155
1147
1156
1148
@ Override
1157
- public void addExtension (ConfigurationExtension extension ) {
1158
- Objects .requireNonNull (extension );
1159
- extensions = Arrays .copyOf (extensions , extensions .length + 1 );
1160
- extensions [extensions .length - 1 ] = extension ;
1149
+ public <T extends ConfigurationExtension > T addExtensionIfAbsent (
1150
+ final Class <T > extensionType , final Supplier <? extends T > supplier ) {
1151
+ for (final ConfigurationExtension extension : extensions ) {
1152
+ if (extensionType .isInstance (extension )) {
1153
+ return extensionType .cast (extension );
1154
+ }
1155
+ }
1156
+ return addExtension (supplier .get ());
1157
+ }
1158
+
1159
+ private <T extends ConfigurationExtension > T addExtension (final T extension ) {
1160
+ extensions .add (Objects .requireNonNull (extension ));
1161
+ return extension ;
1161
1162
}
1162
1163
1163
1164
@ Override
1164
- public <T extends ConfigurationExtension > T getExtension (Class <T > extensionType ) {
1165
+ public <T extends ConfigurationExtension > T getExtension (final Class <T > extensionType ) {
1165
1166
T result = null ;
1166
1167
for (final ConfigurationExtension extension : extensions ) {
1167
1168
if (extensionType .isInstance (extension )) {
1168
1169
if (result == null ) {
1169
- result = ( T ) extension ;
1170
+ result = extensionType . cast ( extension ) ;
1170
1171
} else {
1171
1172
LOGGER .warn (
1172
1173
"Multiple configuration elements found for type {}. Only the first will be used." ,
0 commit comments