content: /**
   * JReversePro - Java Decompiler / Disassembler.
   * Copyright (C) 2008 Karthik Kumar.
   * 
   * Licensed under the Apache License, Version 2.0 (the "License"); 
   * you may not use this file except in compliance with the License. 
   * You may obtain a copy of the License at 
   *  
   *  	http://www.apache.org/licenses/LICENSE-2.0 
   *  
   * Unless required by applicable law or agreed to in writing, software
   * distributed under the License 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 org.jreversepro.parser;
  
  import java.io.DataInputStream;
  import java.io.IOException;
  import java.util.logging.Logger;
  
  import org.jreversepro.CustomLoggerFactory;
  import org.jreversepro.jvm.JVMConstants;
  import org.jreversepro.parser.common.DefaultClassFileParser;
  
  
  public class ClassFileParserFactory {
  
    public static ClassFileParser getClassFileParser(DataInputStream dis)
        throws ClassParserException, IOException {
      assertJVMMagic(dis);
      JVMVersion jvmVersion = readVersion(dis);
      // TODO: Depending on the supported JVM Versions - select one
      // appropriately
      return new DefaultClassFileParser();
    }
  
    /**
     * Reads the Magic number.
     * 
     * @throws ClassParserException
     *           Thrown if class file not in desired format.
     * @throws IOException
     *           Thrown if error in stream of bytes containing the class file.
     */
    private static void assertJVMMagic(DataInputStream dis)
        throws ClassParserException, IOException {
      int magic = dis.readInt();
      if (magic != JVMConstants.MAGIC) {
        throw new ClassParserException("Invalid Magic Number" + magic);
      }
    }
  
    /**
     * Reads the Version of the class file.
     * 
     * @return
     * 
     * @throws ClassParserException
     *           Thrown if class file not in desired format.
     * @throws IOException
     *           Thrown if error in stream of bytes containing the class file.
     */
    private static JVMVersion readVersion(DataInputStream dis) throws IOException {
      JVMVersion jvmVersion = new JVMVersion();
  
      jvmVersion.minor = dis.readShort();
      jvmVersion.major = dis.readShort();
  
      return jvmVersion;
    }
  
    /**
     * @param major
     *          Major version of the JVM.
     * @param minor
     *          Minor version of the JVM. test whether or not the supplied
     *          major/minor class versions are acceptable. (NOTE: we should
     *          probably have a runtime switch to accept all versions since even
     *          though the versions may be incremented, there are typically no
     *          changes to the form of the class files)
     * 
     *          45.3+ is java 1.1 46.0 is java 1.2 47.0 is java 1.3 48.0 is java
     *          1.4
     * 
     * @return true if the major/minor versions are acceptable
     */
    private static boolean supportedMajorMinor(JVMVersion _version) {
      if (_version.major == 45) {
        return (_version.minor >= 3);
      }
  
      if (_version.major >= 46 && _version.major <= 48) {
        return true;
      }
      logger.warning("Major: " + _version.major + " ,Minor: " + _version.minor
          + " not supported ");
      return false;
    }
  
    private ClassFileParserFactory() {
    }
  
    static class JVMVersion {
      short minor;
      short major;
    }
  
    private static Logger logger = CustomLoggerFactory.createLogger();
  
  }
  