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