All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.amazon.ion.apps.SymtabApp Maven / Gradle / Ivy

The newest version!
/*
 * 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 myImports = new ArrayList();
    private ArrayList      mySymbols = new ArrayList();

    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 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);
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy