1 /*
2  * Copyright (c) 2012, 2018, Oracle and/or its affiliates. All rights reserved.
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * This code is free software; you can redistribute it and/or modify it
6  * under the terms of the GNU General Public License version 2 only, as
7  * published by the Free Software Foundation.  Oracle designates this
8  * particular file as subject to the "Classpath" exception as provided
9  * by Oracle in the LICENSE file that accompanied this code.
10  *
11  * This code is distributed in the hope that it will be useful, but WITHOUT
12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14  * version 2 for more details (a copy is included in the LICENSE file that
15  * accompanied this code).
16  *
17  * You should have received a copy of the GNU General Public License version
18  * 2 along with this work; if not, write to the Free Software Foundation,
19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20  *
21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22  * or visit www.oracle.com if you need additional information or have any
23  * questions.
24  */
25 
26 package jdk.jfr.internal.jfc;
27 
28 import java.io.CharArrayReader;
29 import java.io.CharArrayWriter;
30 import java.io.IOException;
31 import java.io.Reader;
32 import java.text.ParseException;
33 import jdk.internal.org.xml.sax.InputSource;
34 import jdk.internal.org.xml.sax.SAXException;
35 import jdk.internal.util.xml.SAXParser;
36 import jdk.internal.util.xml.impl.SAXParserImpl;
37 import jdk.jfr.Configuration;
38 
39 import jdk.jfr.internal.PrivateAccess;
40 
41 /**
42  * Parses a JDK Flight Recorder Configuration file (.jfc)
43  */
44 final class JFCParser {
45     static final String FILE_EXTENSION = ".jfc";
46     private static final int MAXIMUM_FILE_SIZE = 1024 * 1024;
47 
createConfiguration(String name, Reader reader)48     public static Configuration createConfiguration(String name, Reader reader) throws IOException, ParseException {
49         return createConfiguration(name, readContent(reader));
50     }
51 
createConfiguration(String name, String content)52     public static Configuration createConfiguration(String name, String content) throws IOException, ParseException {
53         try {
54             JFCParserHandler ch = new JFCParserHandler();
55             parseXML(content, ch);
56             return PrivateAccess.getInstance().newConfiguration(name, ch.label, ch.description, ch.provider, ch.settings, content);
57         } catch (IllegalArgumentException iae) {
58             throw new ParseException(iae.getMessage(), -1);
59         } catch (SAXException e) {
60             ParseException pe =  new ParseException("Error reading JFC file. " + e.getMessage(), -1);
61             pe.initCause(e);
62             throw pe;
63         }
64     }
65 
parseXML(String content, JFCParserHandler ch)66     private static void parseXML(String content, JFCParserHandler ch) throws SAXException, IOException {
67         CharArrayReader r = new CharArrayReader(content.toCharArray());
68         SAXParser parser = new SAXParserImpl();
69         parser.parse(new InputSource(r), ch);
70     }
71 
readContent(Reader r)72     private static String readContent(Reader r) throws IOException {
73         CharArrayWriter writer = new CharArrayWriter(1024);
74         int count = 0;
75         int ch;
76         while ((ch = r.read()) != -1) {
77             writer.write(ch);
78             count++;
79             if (count >= MAXIMUM_FILE_SIZE) {
80                 throw new IOException("Presets with more than " + MAXIMUM_FILE_SIZE + " characters can't be read.");
81             }
82         }
83         return new String(writer.toCharArray());
84     }
85 }
86