PageRenderTime 45ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 0ms

/app/models/generate_and_format_plan.rb

https://github.com/eedrummer/laika
Ruby | 145 lines | 114 code | 21 blank | 10 comment | 11 complexity | 369d7cc11cc1832b2d23d3b4d541a494 MD5 | raw file
  1. class GenerateAndFormatPlan < TestPlan
  2. test_name "Generate & Format"
  3. pending_actions 'Execute>' => :doc_upload
  4. completed_actions 'Inspect' => :doc_inspect, 'Checklist' => :doc_checklist
  5. serialize :test_type_data, Hash
  6. # Use these relations to access content errors by inspection_type.
  7. # The *_INSPECTION constants are set in config/initializers/laika_globals.rb
  8. has_many :xml_validation_errors, :class_name => 'ContentError',
  9. :foreign_key => 'test_plan_id',
  10. :conditions => { :inspection_type => ::XML_VALIDATION_INSPECTION }
  11. has_many :content_inspection_errors, :class_name => 'ContentError',
  12. :foreign_key => 'test_plan_id',
  13. :conditions => { :inspection_type => ::CONTENT_INSPECTION }
  14. has_many :umls_codesystem_errors, :class_name => 'ContentError',
  15. :foreign_key => 'test_plan_id',
  16. :conditions => { :inspection_type => ::UMLS_CODESYSTEM_INSPECTION }
  17. class ValidationError < StandardError; end
  18. def initialize *args
  19. super
  20. self.test_type_data ||= {}
  21. end
  22. # @return true if UMLS is enabled for this test, false otherwise.
  23. def umls_enabled?
  24. !!test_type_data[:umls_enabled]
  25. end
  26. # Used by validate_clinical_document_content to indicate whether UMLS
  27. # was used. You can check for this flag by calling umls_enabled?
  28. def umls_enabled= flag
  29. test_type_data[:umls_enabled] = flag
  30. end
  31. # This is the primary validation operation for Generate and Format.
  32. def validate_clinical_document_content
  33. document = clinical_document.as_xml_document
  34. validator = Validation.get_validator(clinical_document.doc_type)
  35. logger.debug(validator.inspect)
  36. errors = nil
  37. begin
  38. errors = validator.validate(patient, document)
  39. rescue Exception => e # XXX rescuing everything is almost never a good idea
  40. logger.info("ERROR DURING VALIDATION: #{e.inspect}\n#{e.backtrace.join("\n")}")
  41. raise ValidationError
  42. end
  43. logger.debug(errors.inspect)
  44. logger.debug("PD #{patient} doc #{document}")
  45. content_errors.clear
  46. content_errors.concat errors
  47. if validator.contains_kind_of?(Validators::Umls::UmlsValidator)
  48. self.umls_enabled = true
  49. end
  50. if content_errors.empty?
  51. pass
  52. else
  53. fail
  54. end
  55. content_errors
  56. end
  57. # method used to mark the elements in the document that have errors so they
  58. # can be linked to
  59. def match_errors(doc)
  60. error_map = {}
  61. error_id = 0
  62. error_attributes = []
  63. locs = content_errors.collect{|e| e.location}
  64. locs.compact!
  65. locs.each do |location|
  66. # Get rid of some funky stuff generated by schematron
  67. clean_location = location.gsub("*:", '').gsub("[namespace-uri()='urn:hl7-org:v3']", '')
  68. node = REXML::XPath.first(doc , clean_location)
  69. if(node)
  70. elem = node
  71. if node.class == REXML::Attribute
  72. error_attributes << node
  73. elem = node.element
  74. end
  75. if elem
  76. unless elem.attributes['error_id']
  77. elem.add_attribute('error_id',"#{error_id}")
  78. error_id += 1
  79. end
  80. error_map[location] = elem.attributes['error_id']
  81. end
  82. end
  83. end
  84. return error_map, error_attributes
  85. end
  86. module Actions
  87. def doc_upload
  88. render 'test_plans/doc_upload', :layout => !request.xhr?
  89. end
  90. def doc_validate
  91. test_plan.update_attributes! :clinical_document =>
  92. ClinicalDocument.create!(params[:clinical_document])
  93. begin
  94. test_plan.validate_clinical_document_content
  95. rescue ValidationError
  96. flash[:notice] = "An error occurred while validating the document"
  97. end
  98. redirect_to test_plans_url
  99. end
  100. def doc_checklist
  101. clinical_document = test_plan.clinical_document
  102. doc = clinical_document.as_xml_document(true)
  103. if doc.root && doc.root.name == "ClinicalDocument"
  104. pi = REXML::Instruction.new('xml-stylesheet',
  105. 'type="text/xsl" href="' + relative_url_root +
  106. '/schemas/generate_and_format.xsl"')
  107. doc.insert_after(doc.xml_decl, pi)
  108. render :xml => doc.to_s
  109. else
  110. redirect_to clinical_document.public_filename
  111. end
  112. end
  113. def doc_inspect
  114. if @test_plan.clinical_document.nil?
  115. flash[:notice] = "There is no clinical document content to inspect."
  116. redirect_to test_plans_url
  117. else
  118. @xml_document = @test_plan.clinical_document.as_xml_document
  119. # XXX match_errors sets @error_attributes, used by the node partial
  120. @error_mapping, @error_attributes = @test_plan.match_errors(@xml_document)
  121. end
  122. end
  123. end
  124. end