org.skb.lang.dal.DalPass2_Ast.java Source code

Java tutorial

Introduction

Here is the source code for org.skb.lang.dal.DalPass2_Ast.java

Source

/* Copyright (c) 2000-2011 Sven van der Meer (sven@vandermeer.de)
 * All rights reserved.
 *
 * Redistribution  and  use  in  source  and  binary  forms,  with  or  without
 * modification, are permitted provided that the following conditions are met:
 * 
 *     + Redistributions of source code must retain the above copyright notice,
 *       this list of conditions and the following disclaimer.
 *     + Redistributions  in binary  form must  reproduce the  above copyright
 *       notice, this list  of conditions and  the following disclaimer  in the
 *       documentation and/or other materials provided with the distribution.
 *     + Neither the name of the the author nor the names of its contributors
 *       may be used to endorse or promote products derived from this software
 *       without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS  IS"
 * AND ANY EXPRESS  OR IMPLIED WARRANTIES,  INCLUDING, BUT NOT  LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY  AND FITNESS FOR A  PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN  NO EVENT SHALL  THE COPYRIGHT HOLDER  OR CONTRIBUTORS BE
 * LIABLE  FOR  ANY  DIRECT,  INDIRECT,  INCIDENTAL,  SPECIAL,  EXEMPLARY,   OR
 * CONSEQUENTIAL  DAMAGES  (INCLUDING,  BUT  NOT  LIMITED  TO,  PROCUREMENT  OF
 * SUBSTITUTE GOODS  OR SERVICES;  LOSS OF  USE, DATA,  OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER  CAUSED AND  ON ANY  THEORY OF  LIABILITY, WHETHER  IN
 * CONTRACT,  STRICT LIABILITY,  OR TORT  (INCLUDING NEGLIGENCE  OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE  USE OF THIS SOFTWARE, EVEN IF ADVISED  OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 * 
 * [The BSD License, http://www.opensource.org/licenses/bsd-license.php]
 */

package org.skb.lang.dal;

import java.util.ArrayList;
import java.util.LinkedHashMap;

import org.antlr.runtime.Token;
import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.skb.lang.dal.constants.DalConstants;
import org.skb.tribe.LanguageRuleMap;
import org.skb.util.languages.AtomList;

/**
 * Pass 2 of the DAL parser, mostly looking into semantic analysis.
 *
 * @author     Sven van der Meer <sven@vandermeer.de>
 * @version    v1.0.0 build 110901 (01-Sep-11) with Java 1.6
 */
public class DalPass2_Ast {
    static Logger logger = Logger.getLogger(DalPass2_Ast.class);

    public AtomList atoms;
    private LanguageRuleMap cr;

    // temp Type and Value for testing
    private Token lastBaseType = null;
    private Token lastCommonValue = null;
    private Token lastCommonValueType = null;

    public DalPass2_Ast() {
        this.atoms = AtomList.getInstance();
        this.atoms.scope.clear();
        //System.err.println(this.atoms);

        this.cr = new LanguageRuleMap();
        this.cr.setClassName(DalConstants.Rules.class.getName());
        this.cr.setKey("rule");
        this.cr.loadRules();
    }

    public void testAtom(Token tk) {
        this.atoms.scope.push(tk);
        String atomScope = this.atoms.scope.toString();
        String scopeSep = this.atoms.scope.separator();
        LinkedHashMap<String, String> path = this.buildPathList(atomScope, scopeSep);
        ArrayList<String> keys = new ArrayList<String>(path.keySet());
        int pathSize = StringUtils.split(atomScope, scopeSep).length;

        if (path.size() == 0) {
            System.err.println("error: ID not known [" + tk.getText() + "]");
            return;
        }

        //first can be Repository or Package
        if (path.get(keys.get(0)).equals(DalConstants.Tokens.dalREPOSITORY)) {
            //in Repository, we have only tables, in there lots of fields (nothing to test) and optionally a sequence
            if (path.get(keys.get(2)).equals(DalConstants.Tokens.dalSEQUENCE)) {
                //in sequence we have many fields (level 4)
                if (path.get(keys.get(3)).equals(DalConstants.Tokens.dalFIELD)) {
                    //now remove "sequence@@" and test if Atom exists
                    String t = atomScope.replace("sequence" + scopeSep, "");
                    if (!this.atoms.containsKey(t))
                        System.err.println("erorr in repository: field in sequence not defined for table");
                }
            }
        } else if (path.get(keys.get(0)).equals(DalConstants.Tokens.dalPACKAGE)) {
            //first check for definitions for a repository table
            if (path.get(keys.get(1)).equals(DalConstants.Tokens.dalREPOSITORY)
                    && path.get(keys.get(2)).equals(DalConstants.Tokens.dalTABLE)) {
                //remove the first path entry (current package) and test for the repository, print error only for the actual repo Atom
                if (pathSize == 3
                        && !this.atoms.containsKey(keys.get(1).substring(keys.get(1).indexOf(scopeSep) + 2))) {
                    System.err.println("unknown repository referenced in package");
                }
                //remove the first path entry (current package) and test for the repository table, print error only for the actual repo-table Atom
                if (pathSize == 4
                        && !this.atoms.containsKey(keys.get(2).substring(keys.get(2).indexOf(scopeSep) + 2))) {
                    System.err.println("unknown repository-table referenced in package");
                }
                //check for referenced field in table for repo, error if field is not defined in repo-table
                if (pathSize == 5) {
                    String[] split = StringUtils.split(atomScope, scopeSep);
                    String field = StringUtils.join(new String[] { split[1], split[2], split[4] }, scopeSep);
                    if (!this.atoms.containsKey(field))
                        System.err.println("unknown field for repository-table referenced in package");
                }
            }
            //next check if we are defining a package table
            if (path.get(keys.get(1)).equals(DalConstants.Tokens.dalTABLE)) {
                //in a table, we have lots of fields and optionally a sequence (s=3), but we can only check on the sequence at the end
                if (path.get(keys.get(2)).equals(DalConstants.Tokens.dalFIELD)) {
                    //System.err.println(pathSize+" = table field = "+atomScope);
                }
                if (path.get(keys.get(2)).equals(DalConstants.Tokens.dalSEQUENCE)) {
                    //in sequence we only care about size of 4
                    if (pathSize == 4) {
                        String t = atomScope.replace("sequence" + scopeSep, "");
                        if (!this.atoms.containsKey(t))
                            System.err.println("erorr in repository: field in sequence not defined for table");
                    }
                }
            }
            //next check if we are adding actions to the package
            if (path.get(keys.get(1)).equals(DalConstants.Tokens.dalACTIONS)) {
                //check for the referenced table, size=4
                if (pathSize == 4) {
                    String[] split = StringUtils.split(atomScope, scopeSep);
                    String field = StringUtils.join(new String[] { split[0], split[3] }, scopeSep);
                    if (!this.atoms.containsKey(field))
                        System.err.println("unknown table referenced in action for package");
                }
                //check for the individual fields of the actions, if keys exist in the named table
                if (pathSize == 5) {
                    String[] split = StringUtils.split(atomScope, scopeSep);
                    String field = StringUtils.join(new String[] { split[0], split[3], split[4] }, scopeSep);
                    if (!this.atoms.containsKey(field))
                        System.err.println("unknown key for table referenced in action for package");
                }
            }
            //last check if we are adding data to the package
            if (path.get(keys.get(1)).equals(DalConstants.Tokens.dalDATA)) {
                //first check if referenced table exists in the package
                if (pathSize == 4) {
                    String[] split = StringUtils.split(atomScope, scopeSep);
                    String field = StringUtils.join(new String[] { split[0], split[3] }, scopeSep);
                    if (!this.atoms.containsKey(field))
                        System.err.println("unknown table referenced in data for package");
                }
                if (pathSize == 5) {
                    String[] split = StringUtils.split(atomScope, scopeSep);
                    String field = StringUtils.join(new String[] { split[0], split[3], split[4] }, scopeSep);
                    if (!this.atoms.containsKey(field))
                        System.err.println("unknown key for table referenced in data for package");
                }
            }
        }
    }

    /**
     * Build all individual scopes from current scope, resulting in a list of paths that can be used to analyse the current atom
     * 
     * @param scope the scope of the Atom
     * @param scopeSep the scope separator to be used
     * @return an array list with the constructed paths
     */
    private LinkedHashMap<String, String> buildPathList(String scope, String scopeSep) {

        String[] path = StringUtils.split(scope, scopeSep);
        LinkedHashMap<String, String> ret = new LinkedHashMap<String, String>();
        if (path.length != 0) {
            int i = -1;
            while (++i < path.length) {
                String p = new String();
                for (int k = 0; k <= i; k++) {
                    p += path[k];
                    if (k < i)
                        p += scopeSep;
                }
                try {
                    ret.put(p, this.atoms.get(p).get(AtomList.alValCategory).toString());
                } catch (Exception e) {
                    ret.put(p, new String());
                }
            }
            //fill with empty strings, using 10 as the maximum possible length of the path
            for (int k = i; k < 10; k++) {
                ret.put(Integer.toString(k), new String());
            }
        }
        return ret;
    }

    // temp Type and Value for testing
    public void setLastBaseType(Token tk) {
        this.lastBaseType = tk;
    }

    public void setLastCommonValue(Token tk) {
        this.lastCommonValue = tk;
    }

    public void setLastCommonValueType(Token tk) {
        this.lastCommonValueType = tk;
    }

    public void setLastCommonValuePlusType(Token value, Token type) {
        this.setLastCommonValueType(type);
        this.setLastCommonValue(value);
    }

    public boolean testSN(String category, String catElem) {
        boolean ret = true;
        return ret;
    }
}