class JavaClass::Classpath::TemporaryUnpacker

Unpack a JAR (ZIP) into a temporary folder.

Author

Peter Kofler

Constants

COMMANDS

Command templates for external too like 7zip or zip.

Attributes

folder[R]

The temporary folder. This folder will be deleted after Ruby shuts down.

Public Class Methods

new(jarfile) click to toggle source

Set the given jarfile to unpack.

# File lib/javaclass/classpath/temporary_unpacker.rb, line 26
def initialize(jarfile)
  @jarfile = jarfile

  if !defined?(@@unpack_strategies)
    # use unzip first, fallback by hand
    @@unpack_strategies = COMMANDS.map{ |c| Proc.new{ |jar, folder| TemporaryUnpacker::unpack_shell(c, jar, folder) } } + 
                          [ Proc.new{ |jar, folder| TemporaryUnpacker::unpack_ruby(jar, folder) } ]
  end
end

Private Class Methods

escape_folder(folder) click to toggle source

Escape folder if it contains blanks.

# File lib/javaclass/classpath/temporary_unpacker.rb, line 77
def self.escape_folder(folder)
  if folder =~ / / then "\"#{folder}\"" else folder end
end
unpack_ruby(jarfile, folder) click to toggle source

Unpack jarfile into folder using Ruby's Rubyzip gem. This is very slow. Return true for success.

# File lib/javaclass/classpath/temporary_unpacker.rb, line 92
def self.unpack_ruby(jarfile, folder)
  # warn('unpacking with slow ruby unpacker')
  zip_file = JavaClass::Gems::ZipFile.new(jarfile)
  zip_file.entries do |entry|
    name = entry.name
    next unless entry.file? and name =~ JavaLanguage::CLASS_REGEX # class file

    f_path = File.join(folder, entry.name)
    FileUtils.mkdir_p(File.dirname(f_path))
    unless File.exist?(f_path)
      File.open(f_path, 'wb') { |file| file.write(zip_file.read(name)) } 
    end
  end
  true
end
unpack_shell(command, jarfile, folder) click to toggle source

Unpack jarfile into folder using external executeable using the command string. Return true for success.

# File lib/javaclass/classpath/temporary_unpacker.rb, line 82
def self.unpack_shell(command, jarfile, folder)
  begin
    `#{command.gsub(/<folder>/, escape_folder(folder)).gsub(/<jar>/, escape_folder(jarfile))}`
    $?.to_i == 0
  rescue
    false
  end
end

Public Instance Methods

create_temporary_folder() click to toggle source

Create the temporary folder where it will be unpacked to.

# File lib/javaclass/classpath/temporary_unpacker.rb, line 37
def create_temporary_folder
  folder = File.join(find_temp_folder, "temp_#{File.basename(@jarfile)}_#{Time.now.to_i.to_s}")
  FileUtils.mkdir_p(folder)
  at_exit { FileUtils.rm_r(folder) if File.exist? folder }
  @folder = folder
end
find_temp_folder() click to toggle source

Return the temp folder if a variable is set, else returm /tmp.

# File lib/javaclass/classpath/temporary_unpacker.rb, line 62
def find_temp_folder
  TemporaryUnpacker::escape_folder(
  if ENV['TEMP']
    ENV['TEMP'] # Windows
  elsif ENV['TMP']
    ENV['TMP']
  else
    '/tmp'
  end
  )
end
unpack!() click to toggle source

Unpack the given jar file.

# File lib/javaclass/classpath/temporary_unpacker.rb, line 45
def unpack!
  unless defined?(@folder) && @folder
    raise IOError, 'no temporary folder created'
  end
    
  # Find the first working strategy and keep it
  if ! @@unpack_strategies.first.call(@jarfile, @folder)
    warn("Dropping unpacker for #{@jarfile}. Install 7zip or unzip!")
    @@unpack_strategies.delete_at(0)
    if @@unpack_strategies.empty?
      raise 'no suitable unpack strategy found'
    end
    unpack!
  end
end