1/*
2 * Copyright (c) 2004, 2014, 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
26package sun.jvmstat.perfdata.monitor;
27
28import java.net.*;
29import java.io.*;
30import java.util.*;
31import java.util.regex.*;
32
33/**
34 * Class for parsing alias files. File format is expected to follow
35 * the following syntax:
36 *
37 *     alias name [alias]*
38 *
39 * Java style comments can occur anywhere within the file.
40 * @author Brian Doherty
41 * @since 1.5
42 */
43public class AliasFileParser {
44    private static final String ALIAS = "alias";
45    // 8028357 removed old, inefficient debug logging
46
47    // other variables
48    private URL inputfile;
49    private StreamTokenizer st;
50    private Token currentToken;
51
52    AliasFileParser(URL inputfile) {
53        this.inputfile = inputfile;
54    }
55
56    // value class to hold StreamTokenizer token values
57    private class Token {
58        public String sval;
59        public int ttype;
60
61        public Token(int ttype, String sval) {
62            this.ttype = ttype;
63            this.sval = sval;
64        }
65    }
66
67    /**
68     * method to get the next token as a Token type
69     */
70    private void nextToken() throws IOException {
71        st.nextToken();
72        currentToken = new Token(st.ttype, st.sval);
73    }
74
75    /**
76     * method to match the current Token to a specified token type and
77     * value Throws a SyntaxException if token doesn't match.
78     */
79    private void match(int ttype, String token)
80                 throws IOException, SyntaxException {
81
82        if ((currentToken.ttype == ttype)
83                && (currentToken.sval.compareTo(token) == 0)) {
84            nextToken();
85        } else {
86            throw new SyntaxException(st.lineno());
87        }
88    }
89
90
91    /*
92     * method to match the current Token to a specified token type.
93     * Throws a SyntaxException if token doesn't match.
94     */
95    private void match(int ttype) throws IOException, SyntaxException {
96        if (currentToken.ttype == ttype) {
97            nextToken();
98        } else {
99            throw new SyntaxException(st.lineno());
100        }
101    }
102
103    private void match(String token) throws IOException, SyntaxException {
104        match(StreamTokenizer.TT_WORD, token);
105    }
106
107    /**
108     * method to parse the given input file.
109     */
110    public void parse(Map<String, ArrayList<String>> map) throws SyntaxException, IOException {
111
112        if (inputfile == null) {
113            return;
114        }
115
116        BufferedReader r = new BufferedReader(
117                new InputStreamReader(inputfile.openStream()));
118        st = new StreamTokenizer(r);
119
120        // allow both forms of commenting styles
121        st.slashSlashComments(true);
122        st.slashStarComments(true);
123        st.wordChars('_','_');
124
125        nextToken();
126
127        while (currentToken.ttype != StreamTokenizer.TT_EOF) {
128            // look for the start symbol
129            if ((currentToken.ttype != StreamTokenizer.TT_WORD)
130                    || (currentToken.sval.compareTo(ALIAS) != 0)) {
131                nextToken();
132                continue;
133            }
134
135            match(ALIAS);
136            String name = currentToken.sval;
137            match(StreamTokenizer.TT_WORD);
138
139            ArrayList<String> aliases = new ArrayList<String>();
140
141            do {
142                aliases.add(currentToken.sval);
143                match(StreamTokenizer.TT_WORD);
144
145            } while ((currentToken.ttype != StreamTokenizer.TT_EOF)
146                     && (currentToken.sval.compareTo(ALIAS) != 0));
147
148            map.put(name, aliases);
149        }
150    }
151}
152