require 'tempfile' require 'active_support/core_ext/time/calculations' module MPXJ # Used to read a project plan from a file class Reader @@max_memory_size = nil # Reads a project plan from a file, and returns a Project instance # which provides access to the structure and attributes of the project data. # Note that an optional timezone can be supplied to ensue that all date-time # values returned are in the specified timezone. # # @param file_name [String] the name of the file to read # @param zone [ActiveSupport::TimeZone] an optional timezone # @return [Project] new Project instance def self.read(file_name, zone = nil) project = nil json_file = Tempfile.new([File.basename(file_name, ".*"), '.json']) tz = zone || Time.zone || ActiveSupport::TimeZone["UTC"] begin classpath = Dir["#{File.dirname(__FILE__)}/*.jar"].join(path_separator) java_output = `java -cp \"#{classpath}\" #{jvm_args} net.sf.mpxj.sample.MpxjConvert \"#{file_name}\" \"#{json_file.path}\"` if $?.exitstatus != 0 report_error(java_output) end project = Project.new(json_file, tz) ensure json_file.close json_file.unlink end project end # Allows the caller to set the maximum memory size used by the JVM when processing a schedule. # This is useful when handling large schedules which cause out of memory failures if the JVM's # default maximum memory size is used. The value is either a plain integer number of bytes, # or an integer followed by K, M, or G, e.g. `MPXJ::Reader.max_memory_size="500M"` # # @param value new maximum memory size def self.max_memory_size=(value) @@max_memory_size = value end # @private def self.jvm_args args = [] args << "-Xmx#{@@max_memory_size}" if @@max_memory_size.present? args.join(' ') end # @private def self.path_separator if windows? ";" else ":" end end # @private def self.windows? (/cygwin|mswin|mingw|bccwin|wince|emx/ =~ RUBY_PLATFORM) != nil end # @private def self.report_error(java_output) if java_output.include?('Conversion Error: ') message = java_output.split('Conversion Error: ')[1] if message.include?('Unsupported file type') raise MPXJ::ArgumentError, message else raise MPXJ::RuntimeError, message end else raise MPXJ::UnknownError, "Failed to read file: #{java_output}" end end end end