Package org.dmd.util.parsing

Source Code of org.dmd.util.parsing.DmcUncheckedOIFParser

//  ---------------------------------------------------------------------------
//  dark-matter-data
//  Copyright (c) 2010 dark-matter-data committers
//  ---------------------------------------------------------------------------
//  This program is free software; you can redistribute it and/or modify it
//  under the terms of the GNU Lesser General Public License as published by the
//  Free Software Foundation; either version 3 of the License, or (at your
//  option) any later version.
//  This program is distributed in the hope that it will be useful, but WITHOUT
//  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
//  FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
//  more details.
//  You should have received a copy of the GNU Lesser General Public License along
//  with this program; if not, see <http://www.gnu.org/licenses/lgpl.html>.
//  ---------------------------------------------------------------------------
package org.dmd.util.parsing;

import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.LineNumberReader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.StringTokenizer;

import org.dmd.dmc.DmcValueException;
import org.dmd.dmc.rules.DmcRuleExceptionSet;
import org.dmd.dmc.util.DmcUncheckedObject;
import org.dmd.util.exceptions.Result;
import org.dmd.util.exceptions.ResultException;

/**
* This class parses files that conform to Object Instance Format (OIF).
* <P>
* Object Instance Format is a text-based format that allows for the capture
* of just about any type of data. The kinds of objects that can be represented
* depend on schemas that are defined as part of a Dark Matter Schema (DMS).
* <P>
* At this level of parsing, no real error checking is performed - that will be
* taken care of by the object handler that understands the specifics of the
* schema that should be followed by the objects in the file.
* @see #parseFile
*/

public class DmcUncheckedOIFParser {

    /**
      * Handler to which newly parsed objects will be passed.
      */
    DmcUncheckedOIFHandlerIF    handler;

    /**
     * Indicates the number of errors that the caller is willing to encounter
     * before we halt parsing.
     */
    int     allowedErrorsV;
   
    /**
     * Place to hang on to exceptions (which may include errors/warnings generated by our handler.
     */
    ResultException  exG;
   
    // Indicates the attributes that should have their newlines preserved
    HashMap<String, String>   preserveNL;

    /**
      * Creates a new Object Instance Format parser. As new BasicObjects are created,
      * they will be passed to the object handler for processing.
      */
    public DmcUncheckedOIFParser(DmcUncheckedOIFHandlerIF objHandler) {
        handler         = objHandler;
        allowedErrorsV  = 0;
        exG        = null;
        preserveNL    = new HashMap<String, String>();
    }
   
    public void addPreserveNewlinesAttribute(String an){
      preserveNL.put(an, an);
    }

    /**
     * Allows you to set the number of errors that you're willing to ignore during
     * the parsing. The default is to quit parsing whenever an error is encountered.
     * If you don't care how many errors you find, set the allowedErrors to -1.
     * <P>
     * The parsing will always stop if we encounter a FATAL error (as reflected
     * in the ResultSet).
     */
    public void allowedErrors(int i){
        allowedErrorsV = i;
    }

    /**
     * Parses the specified file and sends the objects to the object handler specified in
     * the constructor.
     * @param fileName The file to be parsed.
     * @throws ResultException, DmcValueException
     * @throws DmcRuleExceptionSet
     */
    public void parseFile(String fileName) throws ResultException, DmcValueException, DmcRuleExceptionSet {
      parseFile(fileName,false);
    }

    /**
     * Parses the specified file and sends the objects to the object handler specified in
     * the constructor.
     * @param fileName The file to be parsed.
     * @param isResource A flag to indicate if the file name refers to a resource e.g. in a JAR. If so,
     * we have to approach the opening of the file differently.
     * @throws ResultException, DmcValueException
     * @throws DmcRuleExceptionSet
     */
    public void parseFile(String fileName, boolean isResource) throws ResultException, DmcValueException, DmcRuleExceptionSet {
        boolean           inObject    = false;
        String            attrName    = null;
        DmcUncheckedObject  uco     = null;
        StringBuffer      attrVal     = new StringBuffer();
        String            val         = null;
        // Note: we replace the friggin' windows backslashes with forward slashes
        String            fn          = fileName.replace('\\', '/');
        int          lastLine  = 0;
        LineNumberReader  in      = null;

        // Reset out global exception instance
        exG = null;

        try {
            // BufferedReader in = new BufferedReader(new FileReader(fileName));
         
          if (isResource){
          InputStreamReader isr = new InputStreamReader(getClass().getResourceAsStream(fn));
          in = new LineNumberReader(isr);           
          }
          else
            in = new LineNumberReader(new FileReader(fileName));
// System.out.println("Reading " + fileName);
            String str;
            while ((str = in.readLine()) != null) {
//DebugInfo.debug("Near line: " + in.getLineNumber());
                if (str.startsWith("*") || str.startsWith("//")){
                    // It's a comment, skip it
                }
                else{
                    StringTokenizer t = new StringTokenizer(str);

                    if (t.countTokens() != 0){
                        if (inObject == false){
                            ArrayList<String> al = new ArrayList<String>();
                            // We're starting a new object - these tokens should be the classes
                            while(t.hasMoreTokens()){
                                al.add(t.nextToken().trim());
                            }

                            uco = new DmcUncheckedObject(al,in.getLineNumber());
                            inObject = true;
                            attrName = null;
                        }
                        else{
                            // We have tokens
                            if (str.startsWith(" ")){
                                // Line continuation
                              if (preserveNL.get(attrName) != null)
                                    attrVal.append("\n" + str);
                              else
                                attrVal.append(str);
                            }
                            else{
                                // A new attribute line
                                if (attrName != null){
                                    // Add the current attribute to the object
                                  val = attrVal.toString().trim();
                                 
                                  if (preserveNL.get(attrName) != null)
                                    val = val.replaceAll("\n", "\\\\n");
                                 
                                    uco.addValue(attrName,new String(val));
                                }

                                // Get the new attribute name
                                attrName = t.nextToken().trim();

                                // Wipe the value buffer
                                attrVal.delete(0,attrVal.length());

                                // Reset it with the contents of the current line
                                attrVal.append(str);

                                // Trim the attribute name and leading spaces
                                attrVal.delete(0,attrName.length());
                                if (attrVal.length() == 0){
                                // We have a missing token value
                                ResultException ex = new ResultException();
                                ex.addError("No value for attribute: " + attrName);
                                ex.setLocationInfo(fileName, in.getLineNumber());
                                throw(ex);
                                }
                                while(attrVal.charAt(0) == ' '){
                                    attrVal.delete(0,1);
                                }
                            }
                        }
                    }
                    else{
                        if (uco != null){
                            // We have a blank line which means we've reached the end of an object - pass off
                            // the current object for processing
                            inObject = false;

                            // Tack on the last attribute
                            if (attrName != null){
                                val = attrVal.toString().trim();
                               
                              if (preserveNL.get(attrName) != null)
                                val = val.replaceAll("\n", "\\\\n");
                             
                                uco.addValue(attrName,new String(val));
                            }

                            try{
                              handler.handleObject(uco,fn, in.getLineNumber());
                            }
                            catch(ResultException ex){
//                              DebugInfo.debug(ex.toString());
                             
                              // If this is the first exception, just hang on to it - we may
                              // wind up adding to it later. Otherwise, just append the results
                              // to our existing exception.
                              if (exG == null)
                                exG = ex;
                              else
                                exG.result.addResults(ex.result);
                             
                              if (exG.result.worst() == Result.FATAL){
                                uco = null;
                                break;
                              }
                             
                                if (allowedErrorsV == -1){
                                    // Couldn't care less about errors! Just go merrily on our way.
                                }
                                else if ((allowedErrorsV == 0) && (exG.result.errors() > 0)){
                                    // Couldn't allow errors - let's bail
                                    uco = null;
                                    break;
                                }
                                else if (exG.result.errors() >= allowedErrorsV){
                                    // We've reached the limits of our patience
                                    uco = null;
                                    break;
                                }

                            }

                            // Reset our object and go on for the next one
                            uco = null;
                        }
                    }
                }

                lastLine = in.getLineNumber();
            }
            in.close();
        }
        catch (IOException e) {
          if (exG == null)
            exG = new ResultException();
         
            exG.result.addResult(Result.FATAL,e.toString());
            exG.result.lastResult().moreMessages("Occurred while reading file: " + fileName);
            uco = null;
        }

        if (uco != null){
            // Finish off for the final attribute and object
            if (attrName != null){
                // Add the current attribute to the object
                // System.out.println("Adding *" + attrVal + "*");
                val = new String(attrVal);
               
              if (preserveNL.get(attrName) != null)
                val = val.replaceAll("\n", "\\\\n");
             
                uco.addValue(attrName,val.trim());
            }

            try{
              handler.handleObject(uco,fn,lastLine);
            }
            catch(ResultException ex){
//              DebugInfo.debug(ex.toString());
             
              // This is here to prevent problems when this same instance of the parser is used
              // in multiple parsing exercises and we don't want to keep throwing/catching the
              // same exception.
              if (ex == exG)
                throw(exG);
             
              if (exG == null)
                exG = ex;
              else
                exG.result.addResults(ex.result);
            }
        }
       
        if (exG != null)
          throw(exG);

    }

}

TOP

Related Classes of org.dmd.util.parsing.DmcUncheckedOIFParser

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.