2424import java .util .Map ;
2525import java .util .Map .Entry ;
2626import java .util .function .Function ;
27+ import java .util .regex .Pattern ;
2728
2829import javax .xml .xpath .XPathConstants ;
2930import javax .xml .xpath .XPathExpression ;
@@ -71,52 +72,51 @@ public class KarafAddonFeatureCheck extends AbstractStaticCheck {
7172 private final Logger logger = LoggerFactory .getLogger (KarafAddonFeatureCheck .class );
7273
7374 private final Map <String , String > featureNamePatternsMap = new LinkedHashMap <>();
74- private final List <String > excludeFeatureNamesList = new ArrayList <>();
75+ private final List <Pattern > excludeAddonsList = new ArrayList <>();
7576
7677 public KarafAddonFeatureCheck () {
7778 setFileExtensions (XML_EXTENSION );
7879 }
7980
80- /**
81- * Comma separated list of binding names (name after pattern applied) of feature names that will be ignored for
82- * checking.
83- *
84- * @param excludeFeatureNames command separated list
85- */
86- public void setExcludeFeatureNames (String excludeFeatureNames ) {
87- if (excludeFeatureNames .trim ().isBlank ()) {
88- return ;
89- }
90- for (String exclude : excludeFeatureNames .split ("," )) {
91- excludeFeatureNamesList .add (exclude );
92- }
93- }
94-
9581 /**
9682 * Comma separated list of key value pairs (separated by colon) transform the calculated expected feature name in
9783 * the actual feature name.
9884 * For example openhab-transform-map:openhab-transformation-map.
9985 * the openhab-transform-map is as expected as derived from the artifactId, but all bundles use transformation.
100- * So with the pattern expected feature name can be constructed.
86+ * So with the map expected feature name can be constructed.
10187 *
102- * @param featureNamePatterns list of key/value pairs of patterns
88+ * @param featureNameMappings list of key/value pairs of patterns
10389 */
104- public void setFeatureNamePatterns (String featureNamePatterns ) {
105- if (featureNamePatterns .trim ().isBlank ()) {
90+ public void setFeatureNameMappings (String featureNameMappings ) {
91+ if (featureNameMappings .trim ().isBlank ()) {
10692 return ;
10793 }
108- for (String pattern : featureNamePatterns .split ("," )) {
94+ for (String pattern : featureNameMappings .split ("," )) {
10995 final String [] keypair = pattern .split (":" );
11096
11197 if (keypair .length == 2 ) {
11298 featureNamePatternsMap .put (keypair [0 ], keypair [1 ]);
11399 } else {
114100 logger .warn ("{} check pattern for option featureNamePatterns is invalid. Value set: {}" ,
115- getClass ().getName (), featureNamePatterns );
101+ getClass ().getName (), featureNameMappings );
116102 }
117103 }
118104 }
119105
106+ /**
107+ * Comma separated list of add-on name patterns that will be excluded from checking.
108+ *
109+ * @param excludeAddonPatterns command separated list
110+ */
111+ public void setExcludeAddonPatterns (String excludeAddonPatterns ) {
112+ if (excludeAddonPatterns .trim ().isBlank ()) {
113+ return ;
114+ }
115+ for (String pattern : excludeAddonPatterns .split ("," )) {
116+ excludeAddonsList .add (Pattern .compile (pattern ));
117+ }
118+ }
119+
120120 @ Override
121121 protected void processFiltered (@ Nullable File file , @ Nullable FileText fileText ) throws CheckstyleException {
122122 if (file == null || fileText == null ) {
@@ -140,19 +140,29 @@ private void checkMissingFeatureFile(File file, FileText fileText) throws Checks
140140 getClass ().getSimpleName (), file .getAbsolutePath ());
141141 return ;
142142 }
143- final File featureFile = new File (file .getParent (), FEATURE_XML_PATH );
143+ String parent = file .getParent ();
144+ final File featureFile = new File (parent , FEATURE_XML_PATH );
144145
145146 if (!featureFile .exists ()) {
146- logMessage (featureFile .toString (), 0 , FEATURE_XML ,
147- MessageFormat .format (MSG_MISSING_FEATURE_XML , featureFile ));
147+ if (isExcludedAddon (parent )) {
148+ logger .debug ("Ignore check on none exisiting feature name {}" , featureFile );
149+ } else {
150+ logMessage (featureFile .toString (), 0 , FEATURE_XML ,
151+ MessageFormat .format (MSG_MISSING_FEATURE_XML , featureFile ));
152+ }
148153 }
149154 }
150155
151156 private void checkFeatureFile (File featureFile , FileText fileText ) throws CheckstyleException {
152157 try {
153158 final String featureFileString = featureFile .getAbsoluteFile ().toString ();
154- final FileText pomFile = new FileText (
155- new File (featureFileString .replace (FEATURE_XML_PATH , "" ), POM_XML_FILE_NAME ),
159+ String addonPath = featureFileString .replace (FEATURE_XML_PATH , "" );
160+
161+ if (isExcludedAddon (new File (addonPath ).getName ())) {
162+ logger .debug ("Ignore check on excluded addon with feature name {}" , featureFile );
163+ return ;
164+ }
165+ final FileText pomFile = new FileText (new File (addonPath , POM_XML_FILE_NAME ),
156166 StandardCharsets .UTF_8 .name ());
157167 final String artifactId = getArtifactId (pomFile );
158168
@@ -170,6 +180,10 @@ private void checkFeatureFile(File featureFile, FileText fileText) throws Checks
170180 }
171181 }
172182
183+ private boolean isExcludedAddon (String parent ) {
184+ return excludeAddonsList .stream ().anyMatch (p -> p .matcher (parent ).find ());
185+ }
186+
173187 private void checkFeatures (File featureFile , String artifactId , FileText fileText , Document featureXML ) {
174188 checkName (featureFile , artifactId , fileText , featureXML , FEATURES_NAME_EXPRESSION ,
175189 name -> !artifactId .equals (name .substring (0 , name .indexOf ('-' ))), MSG_FEATURES_NAME_INVALID ,
@@ -179,17 +193,12 @@ private void checkFeatures(File featureFile, String artifactId, FileText fileTex
179193 private void checkFeature (File featureFile , String artifactId , FileText fileText , Document featureXML ) {
180194 final String featureName = adaptedFeatureName (artifactId );
181195
182- for (String exclude : excludeFeatureNamesList ) {
183- if (exclude .equals (featureName )) {
184- logger .debug ("Ignore check on feature name {}" , featureName );
185- return ;
186- }
187- }
188196 checkName (featureFile , featureName , fileText , featureXML , FEATURE_NAME_EXPRESSION ,
189197 name -> !featureName .equals (name ), MSG_FEATURE_NAME_INVALID , FEATURE_SEARCH );
190198 }
191199
192200 private String adaptedFeatureName (String artifactId ) {
201+ // skip 'org.' part of artifactId by taking substring(4)
193202 String featureName = artifactId .substring (4 ).replaceAll ("\\ ." , "-" );
194203
195204 for (Entry <String , String > entry : featureNamePatternsMap .entrySet ()) {
0 commit comments