src/com/amazon/ion/apps/SymtabApp.java (189 lines of code) (raw):

/* * Copyright 2007-2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"). * You may not use this file except in compliance with the License. * A copy of the License is located at * * http://www.apache.org/licenses/LICENSE-2.0 * * or in the "license" file accompanying this file. This file is distributed * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either * express or implied. See the License for the specific language governing * permissions and limitations under the License. */ package com.amazon.ion.apps; import com.amazon.ion.IonCatalog; import com.amazon.ion.IonException; import com.amazon.ion.IonReader; import com.amazon.ion.IonType; import com.amazon.ion.IonWriter; import com.amazon.ion.SymbolTable; import java.io.IOException; import java.io.OutputStream; import java.util.ArrayList; import java.util.Iterator; public class SymtabApp extends BaseApp { private ArrayList<SymbolTable> myImports = new ArrayList<SymbolTable>(); private ArrayList<String> mySymbols = new ArrayList<String>(); private String mySymtabName; private int mySymtabVersion; //========================================================================= // Static methods public static void main(String[] args) { if (args.length < 1) { System.err.println("Need one file to build symtab"); return; } SymtabApp app = new SymtabApp(); app.doMain(args); } //========================================================================= // Construction and Configuration public SymtabApp() { } //========================================================================= @Override protected int processOptions(String[] args) { for (int i = 0; i < args.length; i++) { String arg = args[i]; if ("--catalog".equals(arg)) { String symtabPath = args[++i]; loadCatalog(symtabPath); } else if ("--import".equals(arg)) { // We'll use the latest version available. String name = args[++i]; IonCatalog catalog = mySystem.getCatalog(); SymbolTable table = catalog.getTable(name); if (table == null) { String message = "There's no symbol table in the catalog named " + name; throw new RuntimeException(message); } myImports.add(table); logDebug("Imported symbol table " + name + "@" + table.getVersion()); } else if ("--name".equals(arg)) { if (mySymtabName != null) { throw new RuntimeException("Multiple names"); } mySymtabName = args[++i]; if (mySymtabName.length() == 0) { throw new RuntimeException("Name must not be empty"); } } else if ("--version".equals(arg)) { if (mySymtabVersion != 0) { throw new RuntimeException("Multiple versions"); } int version = Integer.parseInt(arg); if (version < 1) { throw new RuntimeException("Version must be at least 1"); } if (version != 1) { String message = "Symtab extension not implemented"; throw new UnsupportedOperationException(message); } mySymtabVersion = version; } else { // this arg is not an option, we're done here return i; } } return args.length; } @Override protected boolean optionsAreValid(String[] filePaths) { if (mySymtabName == null) { throw new RuntimeException("Must provide --name"); } // TODO verify that we don't import the same name. if (mySymtabVersion == 0) { mySymtabVersion = 1; } if (filePaths.length == 0) { System.err.println("Must provide list of files to provide symbols"); return false; } return true; } @Override public void processFiles(String[] filePaths) { super.processFiles(filePaths); SymbolTable[] importArray = new SymbolTable[myImports.size()]; myImports.toArray(importArray); SymbolTable mySymtab = mySystem.newSharedSymbolTable(mySymtabName, mySymtabVersion, mySymbols.iterator(), importArray); IonWriter w = mySystem.newTextWriter((OutputStream)System.out); try { // TODO ensure IVM is printed mySymtab.writeTo(w); System.out.println(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } @Override protected void process(IonReader reader) throws IonException { while (reader.hasNext()) { IonType type = reader.next(); // System.err.println("Next: " + type); // System.err.println("isInStruct=" + reader.isInStruct()); String fieldName = reader.getFieldName(); intern(fieldName); internAnnotations(reader); switch (type) { case SYMBOL: { String text = reader.stringValue(); intern(text); break; } case LIST: case SEXP: case STRUCT: { // System.err.println("stepping in"); reader.stepIn(); break; } default: { // do nothing break; } } while (! reader.hasNext() && reader.getDepth() > 0) { // System.err.println("stepping out"); reader.stepOut(); } } } private void internAnnotations(IonReader reader) { Iterator<String> i = reader.iterateTypeAnnotations(); assert i != null; while (i.hasNext()) { String ann = i.next(); intern(ann); } } private void intern(String text) { if (text != null) { if (text.equals("$ion") || text.startsWith("$ion_")) return; mySymbols.add(text); } } }