1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package gov.nasa.pds.tools.dict.parser;
17
18 import gov.nasa.pds.tools.dict.Definition;
19 import gov.nasa.pds.tools.dict.Dictionary;
20 import gov.nasa.pds.tools.dict.DictionaryTokens;
21 import gov.nasa.pds.tools.label.AttributeStatement;
22 import gov.nasa.pds.tools.label.CommentStatement;
23 import gov.nasa.pds.tools.label.Label;
24 import gov.nasa.pds.tools.label.ObjectStatement;
25 import gov.nasa.pds.tools.label.Sequence;
26 import gov.nasa.pds.tools.label.Statement;
27 import gov.nasa.pds.tools.label.antlr.ODLLexer;
28 import gov.nasa.pds.tools.label.antlr.ODLParser;
29 import gov.nasa.pds.tools.label.antlr.ODLTokenTypes;
30 import gov.nasa.pds.tools.label.parser.ParseException;
31 import gov.nasa.pds.tools.label.validate.Status;
32 import gov.nasa.pds.tools.logging.ToolsLogRecord;
33
34 import java.io.IOException;
35 import java.io.InputStream;
36 import java.net.URL;
37 import java.util.ArrayList;
38 import java.util.HashMap;
39 import java.util.Iterator;
40 import java.util.List;
41 import java.util.Map;
42 import java.util.logging.Level;
43 import java.util.logging.Logger;
44
45
46 /***
47 * This class provides the means to parse a PDS compliant data dictionary.
48 * The {@link Dictionary} created can be used for validation purposes or just
49 * to examine the contents programmatically. To parse a dictionary use the following:
50 * <p>
51 * <code>
52 * Dictionary dictionary = DictionaryParser.parse(new URL("<url to dictionar>"));
53 * </code>
54 * <p>If you wanted to turn of aliases the alternative parse method could be used:
55 * <p>
56 * <code>
57 * Dictionary dictionary = DictionaryParser.parse(new URL("<url to dictionar>"), false);
58 * </code>
59 *
60 * @author pramirez
61 * @version $Revision: 2627 $
62 *
63 */
64 public class DictionaryParser implements ODLTokenTypes, DictionaryTokens, Status {
65 private static Logger log = Logger.getLogger(DictionaryParser.class.getName());
66
67 /***
68 * Parses a {@link URL} that is compliant with the PDS Data Dictionary document
69 * and formulates a {@link Dictionary} with aliases turned off.
70 * @param url points to the location of the dictionary
71 * @return a data dictionary with element, group, and object definitions
72 * @throws ParseException thrown when dictionary can not be parsed correctly
73 * @throws IOException thrown when dictionary can not be accessed
74 */
75 public static Dictionary parse(URL url) throws ParseException, IOException {
76 return parse(url, false);
77 }
78
79 /***
80 * Parses a {@link URL} that is compliant with the PDS Data Dictionary document
81 * and formulates a {@link Dictionary} with a flag to indicated whether aliases
82 * should be read in.
83 * @param url points to the location of the dictionary
84 * @param aliasing indicates if aliases should be read in
85 * @return a data dictionary with element, group, and object definitions
86 * @throws ParseException thrown when dictionary can not be parsed correctly
87 * @throws IOException thrown when dictionary can not be accessed
88 */
89 public static Dictionary parse(URL url, boolean aliasing) throws ParseException, IOException {
90 Dictionary dictionary = new Dictionary();
91 InputStream input = url.openStream();
92 ODLLexer lexer = new ODLLexer(input);
93 lexer.setFilename(url.toString());
94 ODLParser parser = new ODLParser(lexer);
95 parser.setFilename(url.toString());
96
97 log.log(new ToolsLogRecord(Level.INFO, "Parsing dictionary.", url.toString()));
98 try {
99 List labels = new ArrayList();
100 dictionary.setStatus(PASS);
101
102 while (input.available() > 0) {
103 Label label = parser.label();
104 dictionary.setStatus(lexer.getStatus());
105 dictionary.setStatus(parser.getStatus());
106 if (label != null)
107 labels.add(label);
108 }
109
110 if (labels != null && labels.size() > 0) {
111
112
113 Label headerLabel = (Label) labels.get(0);
114
115 StringBuffer information = new StringBuffer();
116
117 for (Iterator i = headerLabel.getStatements().iterator(); i.hasNext();) {
118 Statement statement = (Statement) i.next();
119 if (statement instanceof CommentStatement)
120 information.append(((CommentStatement) statement).getComment() + "\n");
121 }
122 dictionary.setInformation(information.toString());
123
124
125
126
127 Map definitions = new HashMap();
128 Map aliases = new HashMap();
129 Map units = new HashMap();
130
131
132
133 for (Iterator i = labels.iterator(); i.hasNext();) {
134 for (Iterator s = ((Label) i.next()).getStatements().iterator(); s.hasNext();) {
135 Statement statement = (Statement) s.next();
136 if (statement instanceof ObjectStatement) {
137 if (ALIAS_LIST.equals(statement.getIdentifier())) {
138 if (aliasing)
139 aliases = generateAliases((ObjectStatement) statement);
140 } else if (UNIT_LIST.equals(statement.getIdentifier()))
141 units = generateUnits((ObjectStatement) statement);
142 else {
143 Definition definition = DefinitionFactory.createDefinition((ObjectStatement) statement);
144 definitions.put(definition.getIdentifier(), definition);
145 }
146 }
147 }
148 }
149
150
151 dictionary.setUnits(units);
152
153
154 if (aliasing) {
155
156 for (Iterator i = aliases.keySet().iterator(); i.hasNext();) {
157 String alias = i.next().toString();
158 Definition d = (Definition) definitions.get(aliases.get(alias));
159 d.addAlias(alias);
160 }
161 }
162
163
164 dictionary.addDefinitions(definitions.values());
165 }
166
167 } catch (Exception ex) {
168 dictionary.setStatus(FAIL);
169 log.log(new ToolsLogRecord(Level.SEVERE, ex.getMessage(), url.toString()));
170 throw new ParseException(ex.getMessage());
171 }
172
173 log.log(new ToolsLogRecord(Level.INFO, "Finshed parsing dictionary.", url.toString()));
174
175 return dictionary;
176 }
177
178 private static Map generateAliases(ObjectStatement object) {
179 Map aliases = new HashMap();
180
181
182
183 AttributeStatement objectAliases = object.getAttribute(OBJECT_ALIASES);
184 if (objectAliases != null) {
185 for (Iterator i = ((Sequence) objectAliases.getValue()).iterator(); i.hasNext();) {
186 Sequence values = (Sequence) i.next();
187 if (values.size() == 2) {
188 String alias = values.get(0).toString();
189 String identifier = values.get(1).toString();
190 aliases.put(alias, identifier);
191 }
192 }
193 }
194
195
196
197 AttributeStatement elementAliases = object.getAttribute(ELEMENT_ALIASES);
198 if (elementAliases != null) {
199 for (Iterator i = ((Sequence) elementAliases.getValue()).iterator(); i.hasNext();) {
200 Sequence values = (Sequence) i.next();
201 if (values.size() == 3) {
202 String alias = values.get(0).toString();
203 String objectContext = values.get(1).toString();
204 String identifier = values.get(2).toString();
205 aliases.put(objectContext + "." + alias, identifier);
206 }
207 }
208 }
209
210 return aliases;
211 }
212
213 private static Map generateUnits(ObjectStatement object) {
214 Map units = new HashMap();
215
216
217 AttributeStatement unitSequence = object.getAttribute(UNIT_SEQUENCE);
218 if (unitSequence != null) {
219 for (Iterator i = ((Sequence) unitSequence.getValue()).iterator(); i.hasNext();) {
220 List unitList = new ArrayList();
221 Sequence values = (Sequence) i.next();
222 for (Iterator v = values.iterator(); v.hasNext();) {
223 String unit = v.next().toString();
224 unitList.add(unit);
225 units.put(unit, unitList);
226 }
227 }
228 }
229 return units;
230 }
231
232 public static void main(String [] args) throws Exception {
233 DictionaryParser.parse(new URL(args[0]));
234 }
235 }