• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2022 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package android.safetycenter.lint
18 
19 import com.android.resources.ResourceFolderType
20 import com.android.tools.lint.detector.api.Category
21 import com.android.tools.lint.detector.api.Context
22 import com.android.tools.lint.detector.api.Detector
23 import com.android.tools.lint.detector.api.Implementation
24 import com.android.tools.lint.detector.api.Issue
25 import com.android.tools.lint.detector.api.Location
26 import com.android.tools.lint.detector.api.OtherFileScanner
27 import com.android.tools.lint.detector.api.Scope
28 import com.android.tools.lint.detector.api.Severity
29 import java.io.IOException
30 import javax.xml.XMLConstants
31 import javax.xml.transform.stream.StreamSource
32 import javax.xml.validation.SchemaFactory
33 import org.xml.sax.SAXException
34 
35 /** Lint check for detecting invalid Safety Center configs */
36 class ConfigSchemaDetector : Detector(), OtherFileScanner {
37 
38     companion object {
39         val ISSUE = Issue.create(
40             id = "InvalidSafetyCenterConfigSchema",
41             briefDescription = "The Safety Center config does not meet the schema requirements",
42             explanation = """The Safety Center config must follow all constraints defined in \
43                 safety_center_config.xsd. Either the config is invalid or the schema is not up to
44                 date.""",
45             category = Category.CORRECTNESS,
46             severity = Severity.ERROR,
47             implementation = Implementation(
48                 ConfigSchemaDetector::class.java,
49                 Scope.OTHER_SCOPE
50             ),
51             androidSpecific = true
52         )
53     }
54 
appliesTonull55     override fun appliesTo(folderType: ResourceFolderType): Boolean {
56         return folderType == ResourceFolderType.RAW
57     }
58 
runnull59     override fun run(context: Context) {
60         if (context.file.name != "safety_center_config.xml") {
61             return
62         }
63         val xsd = StreamSource(
64             ConfigSchemaDetector::class.java.getResourceAsStream("/safety_center_config.xsd")
65         )
66         val xml = StreamSource(context.file.inputStream())
67         val schemaFactory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI)
68         try {
69             val schema = schemaFactory.newSchema(xsd)
70             val validator = schema.newValidator()
71             validator.validate(xml)
72         } catch (e: SAXException) {
73             context.report(
74                 ISSUE,
75                 Location.create(context.file),
76                 e.message!!
77             )
78         } catch (e: IOException) {
79             context.report(
80                 ISSUE,
81                 Location.create(context.file),
82                 e.message!!
83             )
84         }
85     }
86 }