summaryrefslogtreecommitdiff
path: root/report/report_service.rb
blob: 91eefe8653ee7a1f80b87dbaeaabadb3f355d495 (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
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
# = Reports::ReportService
#
# provides complete report webservice functionality
#
module Reports
  
  class ReportService
    
    @@persistance = Reports::ExtendedFileReportPersistance.new
    
    def self.persistance
      @@persistance
    end
    
    def self.instance( home_uri=nil )
      if !defined?@@instance
        @@instance = ReportService.new(home_uri)
      elsif home_uri && @@instance.home_uri != home_uri
        raise "already initialized with different home_uri!!!" 
      end
      @@instance
    end
    
    private
    def initialize(home_uri)
      raise "supposed to be a singleton" if defined?@@instance
      raise "plz specify home_uri" unless home_uri
      LOGGER.info "init report service"
      @home_uri = home_uri
      @@instance = self
    end
  
    public
    # lists all available report types, returns list of uris
    #
    # call-seq:
    #   get_report_types => string
    #
    def get_report_types
      
      LOGGER.info "list all report types"
      Reports::ReportFactory::REPORT_TYPES.collect{ |t| get_uri(t) }.join("\n")+"\n"
    end
    
    # lists all stored reports of a certain type, returns a list of uris
    #
    # call-seq:
    #   get_all_reports(type) => string
    #
    def get_all_reports(type, filter_params)
      
      LOGGER.info "get all reports of type '"+type.to_s+"', filter_params: '"+filter_params.inspect+"'"
      check_report_type(type)
      @@persistance.list_reports(type, filter_params).collect{ |id| get_uri(type,id) }.join("\n")+"\n"
    end
    
    # creates a report of a certain type, __validation_uris__ must contain be a list of validation or cross-validation-uris
    # returns the uir of the report 
    #
    # call-seq:
    #   create_report(type, validation_uris) => string
    # 
    def create_report(type, validation_uris, subjectid=nil, task=nil)
      
      LOGGER.info "create report of type '"+type.to_s+"'"
      check_report_type(type)
      
      # step1: load validations
      raise OpenTox::BadRequestError.new("validation_uris missing") unless validation_uris
      LOGGER.debug "validation_uri(s): '"+validation_uris.inspect+"'"
      validation_set = Reports::ValidationSet.new(validation_uris, subjectid)
      raise OpenTox::BadRequestError.new("cannot get validations from validation_uris '"+validation_uris.inspect+"'") unless validation_set and validation_set.size > 0
      LOGGER.debug "loaded "+validation_set.size.to_s+" validation/s"
      task.progress(10) if task
      
      #step 2: create report of type
      report_content = Reports::ReportFactory.create_report(type, validation_set, 
        OpenTox::SubTask.create(task,10,90))
      LOGGER.debug "report created"
      
      #step 3: persist report if creation not failed
      id = @@persistance.new_report(report_content, type, create_meta_data(type, validation_set, validation_uris), self, subjectid)
      LOGGER.debug "report persisted with id: '"+id.to_s+"'"
      task.progress(100) if task
      
      return get_uri(type, id)
    end
    
    # yields report in a certain format, converts to this format if not yet exists, returns uri of report on server 
    #
    # call-seq:
    #   get_report( type, id, accept_header_value ) => string
    # 
    def get_report( type, id, accept_header_value="text/xml", force_formating=false, params={} )
      
      LOGGER.info "get report '"+id.to_s+"' of type '"+type.to_s+"' (accept-header-value: '"+
        accept_header_value.to_s+"', force-formating:"+force_formating.to_s+" params: '"+params.inspect+"')"
      check_report_type(type)
      format = Reports::ReportFormat.get_format(accept_header_value)
      return @@persistance.get_report(type, id, format, force_formating, params)
    end
    
    # returns a report resource (i.e. image)
    #
    # call-seq:
    #   get_report_resource( type, id, resource ) => string
    # 
    def get_report_resource( type, id, resource )
      
      LOGGER.info "get resource '"+resource+"' for report '"+id.to_s+"' of type '"+type.to_s+"'"
      check_report_type(type)
      return @@persistance.get_report_resource(type, id, resource)
    end
    
    
    # delets a report
    #
    # call-seq:
    #   delete_report( type, id )
    # 
    def delete_report( type, id, subjectid=nil )
      
      LOGGER.info "delete report '"+id.to_s+"' of type '"+type.to_s+"'"
      check_report_type(type)
      @@persistance.delete_report(type, id, subjectid)
    end
    
    # no api-access for this method
    def delete_all_reports( type, subjectid=nil )
      
      LOGGER.info "deleting all reports of type '"+type.to_s+"'"
      check_report_type(type)
      @@persistance.list_reports(type).each{ |id| @@persistance.delete_report(type, id, subjectid) }
    end
    
    def parse_type( report_uri )
      
      raise "invalid uri" unless report_uri.to_s =~/^#{@home_uri}.*/
      type = report_uri.squeeze("/").split("/")[-2]
      check_report_type(type)
      return type
    end
    
    def parse_id( report_uri )
      
      raise "invalid uri" unless report_uri.to_s =~/^#{@home_uri}.*/
      id = report_uri.squeeze("/").split("/")[-1]
      @@persistance.check_report_id_format(id)
      return id
    end
    
    def home_uri
      @home_uri
    end
    
    def get_uri(type, id=nil)
      @home_uri+"/"+type.to_s+(id!=nil ? "/"+id.to_s : "")
    end
    
    protected
    def create_meta_data(type, validation_set, validation_uris)
      # the validation_set contains the resolved single validations
      # crossvalidation uris are only added if given as validation_uris - param
      meta_data = {}
      { :validation_uri => "validation_uris",  
          :model_uri => "model_uris",
          :algorithm_uri => "algorithm_uris" }.each do |key,data|
        tmp = []
        validation_set.validations.each do |v|
          #tmp << v.send(key) if v.public_methods.include?(key.to_s) and v.send(key) and !tmp.include?(v.send(key))
          tmp << v.send(key) if v.send(key) and !tmp.include?(v.send(key))
        end
        meta_data[data.to_sym] = tmp
      end
      cvs = []
      validation_uris.each do |v|
        cvs << v if v =~ /crossvalidation/ and !cvs.include?(v)
      end
      meta_data[:crossvalidation_uris] = cvs
      
      meta_data
    end
    
    def check_report_type(type)
     raise OpenTox::NotFoundError.new("report type not found '"+type.to_s+"'") unless Reports::ReportFactory::REPORT_TYPES.index(type)
    end
    
  end
end