1313 * in this software or its documentation.
1414 */
1515
16- package com .suse .oval ;
16+ package com .suse .oval . parser ;
1717
1818import com .redhat .rhn .domain .rhnpackage .PackageType ;
1919import com .suse .oval .exceptions .OvalParserException ;
6060import java .io .File ;
6161import java .io .FileInputStream ;
6262import java .io .FileNotFoundException ;
63- import java .net .URISyntaxException ;
6463import java .net .URL ;
65- import java . util . List ;
64+
6665import java .util .ArrayList ;
66+ import java .util .List ;
6767import java .util .Objects ;
6868
6969/**
7070 * The Oval Parser is responsible for parsing OVAL(Open Vulnerability and Assessment Language) documents
7171 */
7272public class OvalParser {
73+ private static final int DEFINITIONS_BULK_SIZE = 500 ;
7374 private static final Logger LOG = LogManager .getLogger (OvalParser .class );
7475 private static final List <String > TEST_TYPES = List .of ("rpminfo_test" , "dpkginfo_test" );
7576 private static final List <String > OBJECT_TYPES = List .of ("rpminfo_object" , "dpkginfo_object" );
@@ -81,38 +82,70 @@ public class OvalParser {
8182 * @param ovalFile the OVAL file to parse
8283 * @return the parsed OVAL encapulated in a {@link OvalRootType} object=
8384 * */
84- public OvalRootType parse (File ovalFile ) throws OvalParserException {
85+ public OvalRootType parse (URL ovalFile ) throws OvalParserException {
8586 try {
8687 JAXBContext jaxbContext = JAXBContext .newInstance (OvalRootType .class );
8788 Unmarshaller unmarshaller = jaxbContext .createUnmarshaller ();
8889 return (OvalRootType ) unmarshaller .unmarshal (ovalFile );
8990 }
9091 catch (JAXBException e ) {
91- throw new OvalParserException ("Failed to parse the given OVAL file at: " + ovalFile . getAbsolutePath () , e );
92+ throw new OvalParserException ("Failed to parse the given OVAL file at: " + ovalFile , e );
9293 }
9394 }
9495
95- /**
96- * Parse the given OVAL file from a URL
97- *
98- * @param url the URL to get the OVAL file from
99- * @return the parsed OVAL encapsulated in a {@link OvalRootType} object
100- * */
101- public OvalRootType parse (URL url ) {
96+ public void parseDefinitionsInBulk (File ovalFile , OVALDefinitionsBulkHandler bulkHandler ) {
97+ XMLInputFactory xmlInputFactory = XMLInputFactory .newInstance ();
10298 try {
103- return parseStax (new File (url .toURI ()));
99+ XMLEventReader reader = xmlInputFactory .createXMLEventReader (new FileInputStream (ovalFile ));
100+
101+ List <DefinitionType > definitions = new ArrayList <>();
102+
103+ while (reader .hasNext ()) {
104+ XMLEvent nextEvent = reader .nextEvent ();
105+
106+ if (nextEvent .isStartElement ()) {
107+ String elementName = nextEvent .asStartElement ().getName ().getLocalPart ();
108+ if (elementName .equals ("definition" )) {
109+ DefinitionType definitionType = parseDefinitionType (nextEvent .asStartElement (), reader );
110+ definitions .add (definitionType );
111+
112+ if (definitions .size () == DEFINITIONS_BULK_SIZE ) {
113+ bulkHandler .handle (definitions );
114+ definitions = new ArrayList <>();
115+ }
116+ }
117+ }
118+
119+ if (nextEvent .isEndElement ()) {
120+ if (nextEvent .asEndElement ().getName ().getLocalPart ().equals ("definitions" )) {
121+ if (!definitions .isEmpty ()) {
122+ bulkHandler .handle (definitions );
123+ definitions = new ArrayList <>();
124+ }
125+ }
126+ }
127+ }
104128 }
105- catch (URISyntaxException e ) {
106- throw new RuntimeException (e );
129+ catch (XMLStreamException | FileNotFoundException e ) {
130+ throw new OvalParserException ("Failed to parse OVAL definitions from OVAL file at: "
131+ + ovalFile .getAbsolutePath (), e );
107132 }
108133 }
109134
110- public OvalRootType parseStax (File ovalFile ) {
135+ public List <DefinitionType > parseAllDefinitions (File ovalFile ) {
136+ List <DefinitionType > allDefinitions = new ArrayList <>();
137+
138+ parseDefinitionsInBulk (ovalFile , allDefinitions ::addAll );
139+
140+ return allDefinitions ;
141+ }
142+
143+ public OVALResources parseResources (File ovalFile ) {
111144 XMLInputFactory xmlInputFactory = XMLInputFactory .newInstance ();
112145 try {
113146 XMLEventReader reader = xmlInputFactory .createXMLEventReader (new FileInputStream (ovalFile ));
114147
115- OvalRootType ovalRoot = new OvalRootType ();
148+ OVALResources resources = new OVALResources ();
116149
117150 while (reader .hasNext ()) {
118151 XMLEvent nextEvent = reader .nextEvent ();
@@ -121,54 +154,28 @@ public OvalRootType parseStax(File ovalFile) {
121154 String elementName = nextEvent .asStartElement ().getName ().getLocalPart ();
122155 switch (elementName ) {
123156 case "objects" :
124- ovalRoot .setObjects (parseObjects (reader ));
157+ resources .setObjects (parseObjects (reader ));
125158 break ;
126159 case "states" :
127- ovalRoot .setStates (parseStates (reader ));
160+ resources .setStates (parseStates (reader ));
128161 break ;
129162 case "tests" :
130- ovalRoot .setTests (parseTests (reader ));
131- break ;
132- case "definitions" :
133- ovalRoot .setDefinitions (parseDefinitions (reader ));
163+ resources .setTests (parseTests (reader ));
134164 break ;
135165 default : // Do nothing
136166 }
137167 }
138168 }
139169
140- return ovalRoot ;
141-
170+ return resources ;
142171 }
143172 catch (XMLStreamException | FileNotFoundException e ) {
144- throw new OvalParserException ("Failed to parse the given OVAL file at: " + ovalFile .getAbsolutePath (), e );
173+ throw new OvalParserException (
174+ "Failed to parse the OVAL resources(tests, states and objects) from OVAL file at: " +
175+ ovalFile .getAbsolutePath (), e );
145176 }
146177 }
147178
148- private List <DefinitionType > parseDefinitions (XMLEventReader reader ) throws XMLStreamException {
149- List <DefinitionType > definitions = new ArrayList <>();
150-
151- while (reader .hasNext ()) {
152- XMLEvent nextEvent = reader .nextEvent ();
153-
154- if (nextEvent .isStartElement ()) {
155- if (nextEvent .asStartElement ().getName ().getLocalPart ().equals ("definition" )) {
156- DefinitionType definitionType = parseDefinitionType (nextEvent .asStartElement (), reader );
157- definitions .add (definitionType );
158- }
159- }
160-
161- if (nextEvent .isEndElement ()) {
162- if (nextEvent .asEndElement ().getName ().getLocalPart ().equals ("definitions" )) {
163- return definitions ;
164- }
165- }
166- }
167-
168- throw new OvalParserException ("Unable to find the closing tag for </definitions>" );
169-
170- }
171-
172179 private DefinitionType parseDefinitionType (StartElement definitionElement , XMLEventReader reader )
173180 throws XMLStreamException {
174181 DefinitionType definitionType = new DefinitionType ();
@@ -541,7 +548,6 @@ private StateType parseStateType(StartElement rpmStateElement, XMLEventReader re
541548
542549 rpmStateElement .getAttributes ().forEachRemaining (attribute -> {
543550 String attributeName = attribute .getName ().getLocalPart ();
544-
545551 switch (attributeName ) {
546552 case "id" :
547553 stateType .setId (attribute .getValue ());
@@ -679,7 +685,6 @@ private ObjectType parseObjectType(StartElement rpmObjectElement, XMLEventReader
679685 }
680686 });
681687
682-
683688 while (reader .hasNext ()) {
684689 XMLEvent nextEvent = reader .nextEvent ();
685690 if (nextEvent .isStartElement ()) {
0 commit comments