summaryrefslogtreecommitdiff
path: root/report/util.rb
blob: ca5f3ccaac0ff4a5294aaebcf44975db2b4c8c77 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
# graph-files are generated in the tmp-dir before they are stored
ENV['TMP_DIR'] = File.join(FileUtils.pwd,"reports","tmp") unless ENV['TMP_DIR']


class Array
  def common_prefix()
      self.abbrev.keys.sort_by{|word| -word.size}.last[0..-2]
  end
  
  def remove_common_prefix()
      if self.size > 1
        prefix = self.common_prefix
        if prefix.size>0
          return self.collect{|word| word[prefix.size..-1]}
        end
      end
      self
  end
end

class Object
  
  # checks weather two objects have the same values for __equal_attributes__
  #
  def has_equal_attributes?(equal_attributes, object)
    equal_attributes.each{ |a| return false if send(a) != object.send(a) }
    return true
  end
  
end

# = Reports::Util
#
# utilities
#
module Reports::Util
  
  # groups attributes the into groups with equal values for __equal_attributes__, returns an array with sub-arrays for each group  
  # * see Reports::UtilTest for an example
  #
  # call-seq:
  #   self.group( objects, equal_attributes ) => array
  #
  def self.group( objects, equal_attributes )
    
    result = Array.new
    
    objects.each do |o|
      
      match = false
      result.each do |r|
        if o.has_equal_attributes?(equal_attributes, r[0])
          match = true
          r.push(o)
          break
        end
      end
      
      if !match
        result.push(Array.new)
        result[-1].push(o)
      end
    end
    
    return result    
  end
  
  # checks weather all groups in a grouping (generated by self.group) have have corresponding objects
  # * i.e. for each object in a group, there must be a object in each other group that has equal values for __match_attributes__
  # * see Reports::UtilTest for an example
  # * raises exception if no matching
  #
  # call-seq:
  #   self.check_group_matching( grouped_objects, match_attributes )
  #
  def self.check_group_matching( grouped_objects, match_attributes )
    
    raise OpenTox::BadRequestError.new("less then 2 groups, no matching possible") if grouped_objects.size<2
    first_group = grouped_objects[0]
    other_groups = grouped_objects[1..-1].collect{ |g| g.collect{|o| o }} 
    other_groups.each{ |g| raise OpenTox::BadRequestError.new("groups are not equally sized, matching impossible") if g.size != first_group.size } 
    
    first_group.each do |o|
      
      #puts "match "+o.to_s
      other_groups.each do |group|
        
        match = false  
        group.each do |o2|
          #puts "try "+o2.to_s
          if o.has_equal_attributes?(match_attributes, o2)
            match = true
            group.delete(o2)
            break
          end
        end
        raise OpenTox::BadRequestError.new("no match found for "+inspect_attributes(o, match_attributes)) unless match
      end
    end
  end
  
  # returns the path of a file in directory ENV['TMP_DIR'], beginning with __tmp_file_name__, that does not exist yet 
  #
  # call-seq:
  #   self.create_tmp_file(tmp_file_name) => string
  #
  def self.create_tmp_file(tmp_file_name)

    tmp_file_path = nil
    FileUtils.mkdir ENV['TMP_DIR'] unless File.directory?(ENV['TMP_DIR'])
    raise "TMP_DIR does not exist and cannot be created" unless File.directory?(ENV['TMP_DIR'])
    while (!tmp_file_path || File.exist?(tmp_file_path) )
      tmp_file_path = ENV['TMP_DIR']+"/#{tmp_file_name}.#{Time.now.strftime("%Y-%-m-%d_%H-%M-%S")}.#{rand(11111).to_s}"
    end
    return tmp_file_path
  end
  
  protected
  def self.inspect_attributes(object, attributes)
    res = object.class.to_s+" ("
    res += attributes.collect{ |a| a.to_s+"->"+object.send(a).inspect }.join(", ")
    res += ")"
  end

end