caruby-tissue 1.2.2 → 1.2.3
Sign up to get free protection for your applications and to get access to all the features.
- data/History.txt +4 -0
- data/bin/crtdump +11 -3
- data/bin/{seed → crtseed} +0 -0
- data/conf/annotation/pathology_scg/AdditionalFinding.hbm.xml +19 -0
- data/conf/annotation/pathology_scg/BasePathologyAnnotation.hbm.xml +260 -0
- data/conf/annotation/pathology_scg/BreastMargin.hbm.xml +21 -0
- data/conf/annotation/pathology_scg/BreastMarginInvolved.hbm.xml +15 -0
- data/conf/annotation/pathology_scg/BreastMarginUninvolved.hbm.xml +14 -0
- data/conf/annotation/pathology_scg/CNSMargin.hbm.xml +19 -0
- data/conf/annotation/pathology_scg/CNSMarginLocation.hbm.xml +14 -0
- data/conf/annotation/pathology_scg/CarcinomaInSituStatus.hbm.xml +14 -0
- data/conf/annotation/pathology_scg/ColorectalLocalExcisionMarginUninvolved.hbm.xml +15 -0
- data/conf/annotation/pathology_scg/ColorectalResectedMarginUninvolved.hbm.xml +22 -0
- data/conf/annotation/pathology_scg/Cytogenetics.hbm.xml +15 -0
- data/conf/annotation/pathology_scg/DeepMelanomaMargin.hbm.xml +16 -0
- data/conf/annotation/pathology_scg/Details.hbm.xml +14 -0
- data/conf/annotation/pathology_scg/DirectExtensionOfTumor.hbm.xml +14 -0
- data/conf/annotation/pathology_scg/DistalMargin.hbm.xml +15 -0
- data/conf/annotation/pathology_scg/DistanceFromAnalVerge.hbm.xml +23 -0
- data/conf/annotation/pathology_scg/DistantMetastasis.hbm.xml +19 -0
- data/conf/annotation/pathology_scg/ExcionalBiopsyMarginUninvolved.hbm.xml +15 -0
- data/conf/annotation/pathology_scg/ExcisionalBiopsyColorectalDeepMargin.hbm.xml +15 -0
- data/conf/annotation/pathology_scg/ExcisionalBiopsyColorectalLateralOrMucosalMargin.hbm.xml +15 -0
- data/conf/annotation/pathology_scg/ExtraprostaticExtension.hbm.xml +20 -0
- data/conf/annotation/pathology_scg/ExtraprostaticExtensionTissueSites.hbm.xml +14 -0
- data/conf/annotation/pathology_scg/GleasonScore.hbm.xml +16 -0
- data/conf/annotation/pathology_scg/HistologicGrade.hbm.xml +16 -0
- data/conf/annotation/pathology_scg/HistologicType.hbm.xml +19 -0
- data/conf/annotation/pathology_scg/HistologicVariantType.hbm.xml +14 -0
- data/conf/annotation/pathology_scg/ImmunoPhenotyping.hbm.xml +16 -0
- data/conf/annotation/pathology_scg/Invasion.hbm.xml +16 -0
- data/conf/annotation/pathology_scg/KidneyMarginLocation.hbm.xml +15 -0
- data/conf/annotation/pathology_scg/KidneyNephrectomyMargin.hbm.xml +19 -0
- data/conf/annotation/pathology_scg/LateralMelanomaMargin.hbm.xml +16 -0
- data/conf/annotation/pathology_scg/LocalExcisionColorectalDeepMargin.hbm.xml +15 -0
- data/conf/annotation/pathology_scg/LocalExcisionColorectalLateralMargin.hbm.xml +20 -0
- data/conf/annotation/pathology_scg/LungResectionMargin.hbm.xml +17 -0
- data/conf/annotation/pathology_scg/LungResectionMarginsUninvolved.hbm.xml +14 -0
- data/conf/annotation/pathology_scg/MacroscopicExtentOfTumor.hbm.xml +14 -0
- data/conf/annotation/pathology_scg/MesentricMargin.hbm.xml +15 -0
- data/conf/annotation/pathology_scg/MetastasisTissueSite.hbm.xml +15 -0
- data/conf/annotation/pathology_scg/Microcalcification.hbm.xml +14 -0
- data/conf/annotation/pathology_scg/NottinghamHistologicScore.hbm.xml +17 -0
- data/conf/annotation/pathology_scg/OtherResectedOrgans.hbm.xml +15 -0
- data/conf/annotation/pathology_scg/PancreasMargin.hbm.xml +20 -0
- data/conf/annotation/pathology_scg/PancreasMarginInvolvedByInvasiveCarcinoma.hbm.xml +15 -0
- data/conf/annotation/pathology_scg/PancreasMarginUninvolvedByInvasiveCarcinoma.hbm.xml +20 -0
- data/conf/annotation/pathology_scg/PathologicalStaging.hbm.xml +16 -0
- data/conf/annotation/pathology_scg/PolypConfiguration.hbm.xml +15 -0
- data/conf/annotation/pathology_scg/PrimaryTumorStage.hbm.xml +14 -0
- data/conf/annotation/pathology_scg/ProstateMarginLocation.hbm.xml +15 -0
- data/conf/annotation/pathology_scg/ProximalMargin.hbm.xml +15 -0
- data/conf/annotation/pathology_scg/RadialMargin.hbm.xml +15 -0
- data/conf/annotation/pathology_scg/RadicalProstatectomyMargin.hbm.xml +20 -0
- data/conf/annotation/pathology_scg/RegionalLymphNode.hbm.xml +19 -0
- data/conf/annotation/pathology_scg/SatelliteNodule.hbm.xml +14 -0
- data/conf/annotation/pathology_scg/SpecimenCollectionGroup.hbm.xml +87 -0
- data/conf/annotation/pathology_scg/SpecimenIntegrity.hbm.xml +15 -0
- data/conf/annotation/pathology_scg/SpecimenSize.hbm.xml +17 -0
- data/conf/annotation/pathology_scg/TissueSide.hbm.xml +14 -0
- data/conf/annotation/pathology_scg/TumorSize.hbm.xml +29 -0
- data/conf/annotation/pathology_scg/TumorTissueSite.hbm.xml +20 -0
- data/conf/annotation/pathology_scg/UninvolvedMelanomaMargin.hbm.xml +15 -0
- data/conf/annotation/pathology_specimen/AdditionalFinding.hbm.xml +19 -0
- data/conf/annotation/pathology_specimen/AdditionalPathologicFinding.hbm.xml +18 -0
- data/conf/annotation/pathology_specimen/Details.hbm.xml +15 -0
- data/conf/annotation/pathology_specimen/GleasonScore.hbm.xml +16 -0
- data/conf/annotation/pathology_specimen/HistologicGrade.hbm.xml +16 -0
- data/conf/annotation/pathology_specimen/HistologicType.hbm.xml +19 -0
- data/conf/annotation/pathology_specimen/HistologicVariantType.hbm.xml +14 -0
- data/conf/annotation/pathology_specimen/Invasion.hbm.xml +16 -0
- data/conf/annotation/pathology_specimen/NottinghamHistologicScore.hbm.xml +17 -0
- data/conf/annotation/pathology_specimen/Specimen.hbm.xml +52 -0
- data/conf/annotation/pathology_specimen/SpecimenBaseSolidTissuePathologyAnnotation.hbm.xml +73 -0
- data/examples/galena/lib/galena/cli/seed.rb +0 -21
- data/examples/galena/lib/galena/migration/frozen_shims.rb +6 -5
- data/examples/galena/lib/galena/seed/defaults.rb +0 -5
- data/{lib → examples/galena/lib}/galena.rb +0 -0
- data/lib/catissue/annotation/annotatable.rb +37 -0
- data/lib/catissue/annotation/annotatable_class.rb +255 -0
- data/lib/catissue/annotation/annotation.rb +49 -0
- data/lib/catissue/annotation/annotation_class.rb +277 -0
- data/lib/catissue/annotation/annotation_module.rb +77 -0
- data/lib/catissue/annotation/hibernate_mapping.rb +46 -0
- data/lib/catissue/annotation/proxy.rb +28 -0
- data/lib/catissue/annotation/proxy_class.rb +68 -0
- data/lib/catissue/cli/migrate.rb +2 -2
- data/lib/catissue/cli/smoke.rb +6 -4
- data/lib/catissue/database/annotation/annotation_service.rb +75 -61
- data/lib/catissue/database/annotation/annotator.rb +17 -76
- data/lib/catissue/database/annotation/entity_facade.rb +265 -0
- data/lib/catissue/database/annotation/id_generator.rb +62 -0
- data/lib/catissue/database/annotation/integration_service.rb +105 -59
- data/lib/catissue/database/annotation/reference_writer.rb +150 -0
- data/lib/catissue/database/controlled_values.rb +12 -12
- data/lib/catissue/database.rb +148 -58
- data/lib/catissue/domain/abstract_specimen.rb +40 -14
- data/lib/catissue/domain/abstract_specimen_collection_group.rb +1 -3
- data/lib/catissue/domain/collection_protocol.rb +13 -5
- data/lib/catissue/domain/collection_protocol_event.rb +1 -14
- data/lib/catissue/domain/consent_tier_response.rb +2 -0
- data/lib/catissue/domain/consent_tier_status.rb +5 -3
- data/lib/catissue/domain/container.rb +14 -10
- data/lib/catissue/domain/container_position.rb +8 -0
- data/lib/catissue/domain/container_type.rb +13 -6
- data/lib/catissue/domain/participant.rb +15 -10
- data/lib/catissue/domain/site.rb +9 -3
- data/lib/catissue/domain/specimen.rb +79 -40
- data/lib/catissue/domain/specimen_array.rb +11 -1
- data/lib/catissue/domain/specimen_collection_group.rb +79 -41
- data/lib/catissue/domain/specimen_event_parameters.rb +5 -8
- data/lib/catissue/domain/specimen_position.rb +0 -2
- data/lib/catissue/domain/specimen_requirement.rb +1 -1
- data/lib/catissue/domain/storage_container.rb +109 -48
- data/lib/catissue/domain/storage_type.rb +1 -1
- data/lib/catissue/migration/migrator.rb +6 -14
- data/lib/catissue/resource.rb +18 -8
- data/lib/catissue/util/position.rb +11 -1
- data/lib/catissue/util/storable.rb +18 -11
- data/lib/catissue/util/storage_type_holder.rb +44 -6
- data/lib/catissue/version.rb +1 -1
- metadata +86 -35
- data/bin/migrate.rb +0 -42
- data/bin/seed.rb +0 -43
- data/examples/galena/doc/CaTissue/Participant.html +0 -241
- data/examples/galena/doc/CaTissue/SpecimenCollectionGroup.html +0 -190
- data/examples/galena/doc/CaTissue/StorageContainer.html +0 -179
- data/examples/galena/doc/CaTissue/TissueSpecimen.html +0 -320
- data/examples/galena/doc/CaTissue.html +0 -93
- data/examples/galena/doc/Galena/Seed/Defaults.html +0 -650
- data/examples/galena/doc/Galena/Seed.html +0 -203
- data/examples/galena/doc/Galena.html +0 -172
- data/examples/galena/doc/_index.html +0 -181
- data/examples/galena/doc/class_list.html +0 -36
- data/examples/galena/doc/css/common.css +0 -1
- data/examples/galena/doc/css/full_list.css +0 -53
- data/examples/galena/doc/css/style.css +0 -307
- data/examples/galena/doc/file.README.html +0 -153
- data/examples/galena/doc/file_list.html +0 -38
- data/examples/galena/doc/frames.html +0 -13
- data/examples/galena/doc/index.html +0 -153
- data/examples/galena/doc/js/app.js +0 -202
- data/examples/galena/doc/js/full_list.js +0 -149
- data/examples/galena/doc/js/jquery.js +0 -154
- data/examples/galena/doc/method_list.html +0 -163
- data/examples/galena/doc/top-level-namespace.html +0 -112
- data/lib/README.html +0 -33
- data/lib/catissue/database/annotation/annotatable_service.rb +0 -25
- data/lib/catissue/database/annotation/entity_manager.rb +0 -10
- data/lib/galena/cli/seed.rb +0 -43
- data/lib/galena/migration/filter_shims.rb +0 -43
- data/lib/galena/migration/frozen_shims.rb +0 -53
- data/lib/galena/seed/defaults.rb +0 -109
@@ -0,0 +1,77 @@
|
|
1
|
+
require 'caruby/domain/resource_module'
|
2
|
+
require 'catissue/annotation/annotation'
|
3
|
+
require 'catissue/annotation/annotation_class'
|
4
|
+
require 'catissue/annotation/proxy'
|
5
|
+
require 'catissue/annotation/proxy_class'
|
6
|
+
|
7
|
+
module CaTissue
|
8
|
+
module AnnotationModule
|
9
|
+
include CaRuby::ResourceModule
|
10
|
+
|
11
|
+
# @return [AnnotationClass] the annotation proxy class
|
12
|
+
attr_accessor :proxy
|
13
|
+
|
14
|
+
def self.extend_module(mod, hook, opts)
|
15
|
+
mod.extend(self)
|
16
|
+
mod.initialize_annotation(hook, opts)
|
17
|
+
end
|
18
|
+
|
19
|
+
def initialize_annotation(hook, opts)
|
20
|
+
extend(CaRuby::ResourceModule)
|
21
|
+
@java_package = opts[:package]
|
22
|
+
@svc_nm = opts[:service]
|
23
|
+
create_mixin
|
24
|
+
# Proxy initialization has to set proxy mid-initialization.
|
25
|
+
# That is why @proxy is writable. Although setting @proxy
|
26
|
+
# is redundant here, do so since that is the better approach
|
27
|
+
# and will be necessary if and when proxy init is cleaned up.
|
28
|
+
@proxy = import_proxy(hook)
|
29
|
+
@proxy.extend(Annotation::ProxyClass)
|
30
|
+
end
|
31
|
+
|
32
|
+
# Ensures that each primary annotation in this module has a proxy reference attribute.
|
33
|
+
# The primary annotation creates a proxy attribute if necessary.
|
34
|
+
def ensure_proxy_attributes_are_defined
|
35
|
+
@rsc_classes.each { |klass| klass.ensure_primary_has_proxy(@proxy) }
|
36
|
+
end
|
37
|
+
|
38
|
+
# Builds an annotation dependency hierarchy starting at the proxy.
|
39
|
+
def add_annotation_dependents
|
40
|
+
@proxy.add_annotation_dependents
|
41
|
+
end
|
42
|
+
|
43
|
+
def persistence_service
|
44
|
+
@ann_svc ||= Database.instance.annotator.create_annotation_service(@svc_nm)
|
45
|
+
end
|
46
|
+
|
47
|
+
private
|
48
|
+
|
49
|
+
def create_mixin
|
50
|
+
module_eval("module Resource; end")
|
51
|
+
@mixin = const_get('Resource')
|
52
|
+
mod = self
|
53
|
+
@mixin.module_eval do
|
54
|
+
include Annotation
|
55
|
+
|
56
|
+
@domain_module = mod
|
57
|
+
def self.included(klass)
|
58
|
+
super
|
59
|
+
@domain_module.add_class(klass)
|
60
|
+
klass.extend(AnnotationClass)
|
61
|
+
logger.debug { "#{klass.qp} marked as an annotation class." }
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
def import_proxy(hook)
|
67
|
+
# the annotation proxy Java class name
|
68
|
+
proxy_nm = hook.name.demodulize
|
69
|
+
logger.debug { "Importing #{hook.qp} annotation #{qp} hook proxy Java class..." }
|
70
|
+
begin
|
71
|
+
const_get(proxy_nm)
|
72
|
+
rescue CaRuby::JavaIncludeError
|
73
|
+
raise AnnotationError.new("#{hook.qp} annotation #{qp} does not have a hook proxy class - #{$!}")
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
require 'xmlsimple'
|
2
|
+
require 'caruby/util/inflector'
|
3
|
+
require 'catissue/annotation/annotation'
|
4
|
+
|
5
|
+
module CaTissue
|
6
|
+
module Annotation
|
7
|
+
# Annotation class Hibernate mapping encapsulation.
|
8
|
+
#
|
9
|
+
# caTissue alert - caTissue doesn't appear to use Hibernate for DEs. The mappings are incorrect
|
10
|
+
# and should not be used.
|
11
|
+
class HibernateMapping
|
12
|
+
|
13
|
+
attr_accessor :table
|
14
|
+
|
15
|
+
def initialize(klass)
|
16
|
+
hbm = hibernate_mapping(klass)
|
17
|
+
@table = hbm['table']
|
18
|
+
@attr_col_hash = {}
|
19
|
+
hbm['property'].each do |name, md|
|
20
|
+
@attr_col_hash[name.underscore.to_sym] = md['column']
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def column(attribute)
|
25
|
+
@attr_col_hash[attribute]
|
26
|
+
end
|
27
|
+
|
28
|
+
private
|
29
|
+
|
30
|
+
HBM_DIR = File.join(File.dirname(__FILE__), '..', '..', '..', 'conf', 'annotation')
|
31
|
+
|
32
|
+
HBM_OPTS = { 'KeyAttr' => 'name' }
|
33
|
+
|
34
|
+
def hibernate_mapping(klass)
|
35
|
+
file = hibernate_mapping_file(klass)
|
36
|
+
conf = XmlSimple.xml_in(file, HBM_OPTS)
|
37
|
+
conf['class'][klass.name.demodulize]
|
38
|
+
end
|
39
|
+
|
40
|
+
def hibernate_mapping_file(klass)
|
41
|
+
dir = klass.java_class.name[/\w+/]
|
42
|
+
File.join(HBM_DIR, dir, "#{klass.name.demodulize}.hbm.xml")
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module CaTissue
|
2
|
+
module Annotation
|
3
|
+
# {CaTissue::Resource} annotation hook proxy mix-in.
|
4
|
+
module Proxy
|
5
|
+
# The hook proxy identifier is the hook identifier.
|
6
|
+
# This method delegates to the hook.
|
7
|
+
#
|
8
|
+
# @return [Integer] the hook identifier
|
9
|
+
def identifier
|
10
|
+
hook.identifier if hook
|
11
|
+
end
|
12
|
+
|
13
|
+
# The hook proxy identifier cannot be set directly. Assignment is a no-op.
|
14
|
+
#
|
15
|
+
# @param [Integer] value the (ignored) identifier value
|
16
|
+
def identifier=(value); end
|
17
|
+
|
18
|
+
# Sets the +id+ Java property to the hook identifier.
|
19
|
+
# This method must be called before saving an annotation that references this proxy.
|
20
|
+
def ensure_identifier_reflects_hook
|
21
|
+
if getId.nil? then
|
22
|
+
setId(hook.identifier)
|
23
|
+
logger.debug { "Set annotation proxy #{self} identifier to that of the hook entity #{hook.qp}." }
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,68 @@
|
|
1
|
+
require 'set'
|
2
|
+
require 'catissue/annotation/annotation'
|
3
|
+
require 'catissue/annotation/proxy'
|
4
|
+
|
5
|
+
module CaTissue
|
6
|
+
module Annotation
|
7
|
+
# Annotation hook proxy class mix-in.
|
8
|
+
module ProxyClass
|
9
|
+
# @return [AnnotatableClass] the hook class for this proxy
|
10
|
+
attr_reader :hook
|
11
|
+
|
12
|
+
# @param [Class] klass the proxy class
|
13
|
+
def self.extended(klass)
|
14
|
+
super
|
15
|
+
klass.class_eval { include Proxy }
|
16
|
+
end
|
17
|
+
|
18
|
+
def annotation_attributes
|
19
|
+
@ann_attrs ||= domain_attributes.compose { |attr_md| attr_md.type < Annotation }
|
20
|
+
end
|
21
|
+
|
22
|
+
# Sets this proxy's hook to the given class.
|
23
|
+
# Creates the proxy => hook attribute with the given hook => proxy inverse.
|
24
|
+
#
|
25
|
+
# @param [Class] klass the hook class
|
26
|
+
# @param [Symbol] inverse the hook class hook => proxy attribute
|
27
|
+
def set_hook(klass, inverse)
|
28
|
+
@hook = klass
|
29
|
+
# Make a new hook reference attribute.
|
30
|
+
attr_accessor(:hook)
|
31
|
+
# The attribute type is the given hook class.
|
32
|
+
add_attribute(:hook, klass)
|
33
|
+
# Setting one end of the hook <-> proxy association sets the other end.
|
34
|
+
set_attribute_inverse(:hook, inverse)
|
35
|
+
logger.debug { "Added #{klass.qp} annotation proxy => hook attribute with inverse #{klass.qp}.#{inverse}." }
|
36
|
+
end
|
37
|
+
|
38
|
+
# Adds each proxy => annotation reference as a dependent attribute.
|
39
|
+
def add_annotation_dependents
|
40
|
+
annotation_attributes.each_metadata do |attr_md|
|
41
|
+
attr_md.type.add_dependent_attributes
|
42
|
+
attr_md.type.proxy = self
|
43
|
+
end
|
44
|
+
annotation_attributes.each_metadata do |attr_md|
|
45
|
+
attr_md.type.add_dependent_attribute_closure
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
# Creates a reference attribute from this proxy to the given primary {Annotation} class.
|
50
|
+
#
|
51
|
+
# @param [Class] klass the annotation class
|
52
|
+
# @param [Symbol] inverse the annotation => proxy attribute
|
53
|
+
def create_annotation_attribute(klass, inverse)
|
54
|
+
# the new attribute symbol
|
55
|
+
attr = klass.name.demodulize.underscore.pluralize.to_sym
|
56
|
+
logger.debug { "Creating annotation proxy #{qp} attribute #{attr} to hold primary annotation #{klass.qp} instances..." }
|
57
|
+
# Define the access methods: the reader creates a new set on demand to hold the annotations.
|
58
|
+
attr_create_on_demand_accessor(attr) { Set.new }
|
59
|
+
# add the annotation collection attribute
|
60
|
+
add_attribute(attr, klass, :collection)
|
61
|
+
# make the hook attribute which delegates to this proxy
|
62
|
+
@hook.create_annotation_attribute(domain_module, attr)
|
63
|
+
# set the attribute inverse
|
64
|
+
set_attribute_inverse(attr, inverse)
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
data/lib/catissue/cli/migrate.rb
CHANGED
@@ -13,13 +13,13 @@ module CaTissue
|
|
13
13
|
# objects. This is used for testing a migration dry run. It is recommended that the trial run
|
14
14
|
# protocol is set to a test protocol as well.
|
15
15
|
SPECS = [
|
16
|
-
[:input, "input", "Source file to migrate"],
|
16
|
+
[:input, "-i", "input", "Source file to migrate"],
|
17
17
|
[:target, "-t", "--target CLASS", "Migration target class"],
|
18
18
|
[:mapping, "-m", "--mapping FILE", "The input field => caTissue attribute mapping file"],
|
19
19
|
[:shims, "-s", "--shims FILE[,FILE...]", Array, "Migration customization shim files to load"],
|
20
20
|
[:bad, "-b", "--bad FILE", "Write each invalid record to the given file and continue migration"],
|
21
21
|
[:unique, "-u", "--unique", "Make the migrated objects unique for testing"],
|
22
|
-
[:offset, "--offset N", Integer, "Number of input records to skip before starting the migration"]
|
22
|
+
[:offset, "-o", "--offset N", Integer, "Number of input records to skip before starting the migration"]
|
23
23
|
]
|
24
24
|
|
25
25
|
# Creates a {CaTissue::CLI::Migrate} command with the given standard command line specifications
|
data/lib/catissue/cli/smoke.rb
CHANGED
@@ -11,7 +11,9 @@ module CaTissue
|
|
11
11
|
|
12
12
|
private
|
13
13
|
|
14
|
-
|
14
|
+
DEF_SITE = CaTissue::Site.default_site
|
15
|
+
|
16
|
+
DB_MSG = "Verifying database access by searching for the pre-defined #{DEF_SITE.name} Site..."
|
15
17
|
|
16
18
|
# Runs the smoke test.
|
17
19
|
def execute
|
@@ -23,7 +25,7 @@ module CaTissue
|
|
23
25
|
|
24
26
|
def find_in_transit_site
|
25
27
|
begin
|
26
|
-
site =
|
28
|
+
site = DEF_SITE.find
|
27
29
|
rescue Exception => e
|
28
30
|
logger.error("caTissue database access was unsuccessful - #{e}:\n#{e.backtrace.qp}")
|
29
31
|
puts "caTissue database access was unsuccessful - #{e}."
|
@@ -31,11 +33,11 @@ module CaTissue
|
|
31
33
|
end
|
32
34
|
|
33
35
|
if site then
|
34
|
-
puts "The #{
|
36
|
+
puts "The #{DEF_SITE.name} Site was found with identifier #{site.identifier}."
|
35
37
|
puts "Smoke test successful."
|
36
38
|
exit 0
|
37
39
|
else
|
38
|
-
puts "The #{
|
40
|
+
puts "The #{DEF_SITE.name} Site was not found."
|
39
41
|
puts "Smoke test unsuccessful."
|
40
42
|
exit 69 # service unavailable error status
|
41
43
|
end
|
@@ -1,79 +1,93 @@
|
|
1
1
|
require 'caruby/util/inflector'
|
2
|
+
require 'caruby/database/sql_executor'
|
2
3
|
require 'caruby/database/persistence_service'
|
3
|
-
require '
|
4
|
+
require 'catissue/annotation/annotatable'
|
4
5
|
|
5
6
|
module CaTissue
|
6
7
|
module Annotation
|
7
8
|
# An AnnotationService queries and saves CaTissue annotations.
|
8
9
|
class AnnotationService < CaRuby::PersistenceService
|
9
|
-
# The IdGenerator calls the caTissue entity manager to create a new identifier for
|
10
|
-
# an annotation.
|
11
|
-
class IdGenerator
|
12
|
-
# Creates a new IdGenerator with the given caTissue entity_manager.
|
13
|
-
def initialize(entity_manager)
|
14
|
-
super()
|
15
|
-
@entity_manager = entity_manager
|
16
|
-
end
|
17
|
-
|
18
|
-
# Returns a new identifier for the given annotation object.
|
19
|
-
def next_identifier(annotation)
|
20
|
-
logger.debug { "Generating identifier for annotation #{annotation}..." }
|
21
|
-
id = @entity_manager.get_next_identifier_for_entity(annotation.class.qp).to_i
|
22
|
-
# work-around caTissue bug - use a high number that won't conflict with the autogenerated range
|
23
|
-
# cf. https://cabig-kc.nci.nih.gov/Biospecimen/forums/viewtopic.php?f=19&t=404&sid=786325c9c46503529a2b64f0b66fed0a
|
24
|
-
if id.nil? or id.zero? then
|
25
|
-
id = Uniquifier.qualifier
|
26
|
-
logger.warn("Entity manager did not create annotation identifier; using id #{id}.")
|
27
|
-
end
|
28
|
-
id
|
29
|
-
end
|
30
|
-
end
|
31
|
-
|
32
10
|
# Creates an AnnotationService for the given CaTissue::Database, service name and options.
|
33
11
|
#
|
34
|
-
#
|
35
|
-
#
|
36
|
-
#
|
37
|
-
#
|
38
|
-
#
|
39
|
-
|
40
|
-
|
12
|
+
# @param [CaTissue::Database] database the database
|
13
|
+
# @param [String] name the caTissue DE service name
|
14
|
+
# @param (see CaRuby::PersistenceService#initialize)
|
15
|
+
# @option opts :hook the required hook class
|
16
|
+
# @option opts :integration_service the required IntegrationService
|
17
|
+
# @option opts (see CaRuby::PersistenceService#initialize)
|
18
|
+
def initialize(database, name, opts)
|
19
|
+
super(name, opts)
|
41
20
|
@database = database
|
42
|
-
@
|
43
|
-
@
|
44
|
-
entity_manager = Options.get(:entity_manager, options)
|
45
|
-
@id_generator = IdGenerator.new(entity_manager)
|
46
|
-
end
|
47
|
-
|
48
|
-
# Query the given domain object obj with the given attribute path. The query result is
|
49
|
-
# an array of CaRuby::Annotation objects. Overrides {CaRuby::PersistenceService#query} to
|
50
|
-
# delegate to the caTissue integration service when the penultimate search class is this
|
51
|
-
# AnnotationService anchor class, e.g.:
|
52
|
-
# query(CaTissue::SpecimenCollectionGroup.new(:name => 'Biobank_1_5'), :base_pathology_annotation)
|
53
|
-
# or
|
54
|
-
# query(CaTissue::ReceivedEventParameters.new(:user => user), :specimen_collection_group, :base_pathology_annotation)
|
55
|
-
def query(obj, *path)
|
56
|
-
# delegate path[0...-1] to database unless path.length < 2
|
57
|
-
return @database.query(obj, *path[0...-1]).map { |fetched| query(fetched, path[-1]) }.flatten unless path.length < 2
|
58
|
-
return super unless @anchor_class === obj.class
|
59
|
-
# fetch the anchor objects if necessary
|
60
|
-
return @database.query(obj).map { |fetched| query(fetched, *path) }.flatten if obj.identifier.nil?
|
61
|
-
# obj is an anchor with an identifier; make a template
|
62
|
-
template = obj.copy(:identifier)
|
63
|
-
# delegate to the integration service to find the anchor annotations
|
64
|
-
@integration_service.query(template, *path)
|
21
|
+
@database.add_persistence_service(self)
|
22
|
+
@int_svc = opts[:integration_service]
|
65
23
|
end
|
66
24
|
|
67
|
-
# Augments the CaRuby::PersistenceService create method to handle caTissue annotation
|
68
|
-
# e.g
|
69
|
-
#
|
25
|
+
# Augments the {CaRuby::PersistenceService} create method to handle caTissue annotation
|
26
|
+
# service peculiarities, e.g.:
|
27
|
+
# * assigns the identifier, since assignment is not done automatically as is the case with the
|
28
|
+
# default application service
|
29
|
+
# * associate the annotation to the hook object
|
30
|
+
# * Save all referenced annotation objects
|
31
|
+
#
|
32
|
+
# This method can only be called on primary annotation objects. A _primary_ annotation
|
33
|
+
# is a top-level annotation which has a reference to the {Annotation#hook} which is
|
34
|
+
# being annotated.
|
35
|
+
#
|
36
|
+
# @param [Annotation] annotation the annotation object to create
|
37
|
+
# @return [Annotation] the annotation
|
70
38
|
def create(annotation)
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
39
|
+
logger.debug { "Creating annotation #{annotation.qp}..." }
|
40
|
+
# get the hook
|
41
|
+
hook = annotation.hook
|
42
|
+
# If no hook, then this is not a primary annotation. In that case, find a referenced
|
43
|
+
# primary annotation.
|
44
|
+
if hook then
|
45
|
+
time { create_primary_annotation(annotation, hook) }
|
46
|
+
else
|
47
|
+
create_secondary_annotation(annotation)
|
48
|
+
end
|
49
|
+
logger.debug { "Created annotation #{annotation}." }
|
75
50
|
annotation
|
76
51
|
end
|
52
|
+
|
53
|
+
private
|
54
|
+
|
55
|
+
# @param annotation (see #create)
|
56
|
+
# @param [Annotable] the annotatable object referenced by this annotation
|
57
|
+
def create_primary_annotation(annotation, hook)
|
58
|
+
# write the annotation records
|
59
|
+
create_annotation_object(annotation)
|
60
|
+
# Create the "cascaded" references.
|
61
|
+
annotation.class.save_dependent_attributes(annotation)
|
62
|
+
# If the annotation references a hook, then delegate to the integration service to associate
|
63
|
+
# the hook to the annotation.
|
64
|
+
@int_svc.associate(hook, annotation)
|
65
|
+
end
|
66
|
+
|
67
|
+
def create_secondary_annotation(annotation)
|
68
|
+
# the owner annotation
|
69
|
+
ownr = annotation.owner
|
70
|
+
if ownr.nil? then
|
71
|
+
raise AnnotationError.new("Cannot create secondary annotation #{annotation.qp} since it does not have an owner")
|
72
|
+
end
|
73
|
+
# creating the owner creates this secondary
|
74
|
+
create(ownr)
|
75
|
+
end
|
76
|
+
|
77
|
+
# @see #create
|
78
|
+
def create_annotation_object(annotation)
|
79
|
+
# can't create a proxy
|
80
|
+
if Proxy === annotation then
|
81
|
+
raise AnnotationError.new("#{annotation} annotation proxy create is not supported")
|
82
|
+
end
|
83
|
+
# The sequence generator next id.
|
84
|
+
annotation.identifier = EntityFacade.instance.next_identifier(annotation)
|
85
|
+
# Ensure that the proxy record is up-to-date.
|
86
|
+
annotation.ensure_proxy_reflects_hook
|
87
|
+
|
88
|
+
# Delegate to standard record create.
|
89
|
+
app_service.create_object(annotation)
|
90
|
+
end
|
77
91
|
end
|
78
92
|
end
|
79
93
|
end
|
@@ -1,84 +1,25 @@
|
|
1
|
-
require 'caruby/util/properties'
|
2
1
|
require 'catissue/database/annotation/integration_service'
|
3
|
-
require 'catissue/database/annotation/annotatable_service'
|
4
2
|
require 'catissue/database/annotation/annotation_service'
|
5
|
-
require 'catissue/database/annotation/
|
3
|
+
require 'catissue/database/annotation/entity_facade'
|
6
4
|
|
7
5
|
module CaTissue
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
# Returns the CaRuby::PersistenceService for the given klass, or nil if klass is neither
|
21
|
-
# annotatable nor an annotation.
|
22
|
-
def service(klass)
|
23
|
-
annotatable_service(klass) or annotation_service(klass)
|
24
|
-
end
|
25
|
-
|
26
|
-
private
|
27
|
-
|
28
|
-
# Returns the Annotation::AnnotatableService for the given klass, or nil if klass is not annotatable.
|
29
|
-
def annotatable_service(klass)
|
30
|
-
return @anchor_svc_hash[klass] ||= create_annotatable_service(klass) if JavaImport::AnnotatableClass === klass
|
31
|
-
annotatable_service(klass.superclass) if klass.superclass
|
32
|
-
end
|
33
|
-
|
34
|
-
# Returns the Annotation::AnnotatorService for the given klass, or nil if klass is not an annotation.
|
35
|
-
def annotation_service(klass)
|
36
|
-
return @ann_mod_svc_hash[klass.annotation_module] ||= create_annotation_service(klass.annotation_module) if JavaImport::AnnotationClass === klass
|
37
|
-
annotation_service(klass.superclass) if klass.superclass
|
38
|
-
end
|
39
|
-
|
40
|
-
def create_annotatable_service(klass)
|
41
|
-
Annotation::AnnotatableService.new(@database, @database.persistence_service, @integration_service)
|
42
|
-
end
|
43
|
-
|
44
|
-
def create_annotation_service(mod)
|
45
|
-
Annotation::AnnotationService.new(@database, mod.service, :anchor => mod.anchor_class,
|
46
|
-
:integration_service => @integration_service, :entity_manager => @entity_manager)
|
47
|
-
end
|
6
|
+
# An Annotator creates annotation services for annotatable and annotation classes.
|
7
|
+
class Annotator
|
8
|
+
attr_reader :integration_service
|
9
|
+
|
10
|
+
# Initializes a new Annotator for the given database.
|
11
|
+
#
|
12
|
+
# @param [CaTissue::Database] the database
|
13
|
+
def initialize(database)
|
14
|
+
@database = database
|
15
|
+
#the sole DE integration service, used by the annotation services
|
16
|
+
@integration_service = Annotation::IntegrationService.new
|
17
|
+
end
|
48
18
|
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
@pkg_svc_hash = {}
|
54
|
-
#the sole DE integration service, used by the annotation services
|
55
|
-
integration_service = Annotation::IntegrationService.new
|
56
|
-
entity_manager = Annotation::EntityManager.instance
|
57
|
-
# the anchor class => { package => { attribute => type } } hash
|
58
|
-
anchor_pkg_attrs_hash = CaTissue.access_properties[CaRuby::Domain::Properties::ANNOTATIONS_PROP]
|
59
|
-
return {} if anchor_pkg_attrs_hash.nil?
|
60
|
-
# the package => service name hash
|
61
|
-
pkg_svc_nm_hash = CaTissue.access_properties[CaRuby::Domain::Properties::ANN_SVCS_PROP]
|
62
|
-
if pkg_svc_nm_hash.nil? then
|
63
|
-
raise CaRuby::ConfigurationError.new("Annotation service property missing: #{CaRuby::Domain::Properties::ANN_SVCS_PROP}")
|
64
|
-
end
|
65
|
-
# build the anchor => service and package => service hashes
|
66
|
-
anchor_service = Annotation::AnnotatableService.new(database, database.persistence_service, integration_service)
|
67
|
-
# make an annotatable service for each anchor and an annotator service for each package
|
68
|
-
anchor_pkg_attrs_hash.each do |anchor_cls_nm, pkg_signatures_hash|
|
69
|
-
anchor_class = CaTissue.const_get(anchor_cls_nm)
|
70
|
-
@anchor_svc_hash[anchor_class] = anchor_service
|
71
|
-
pkg_signatures_hash.each do |pkg, signatures|
|
72
|
-
svc_nm = pkg_svc_nm_hash[pkg]
|
73
|
-
if svc_nm.nil? then
|
74
|
-
raise CaRuby::DatabaseError.new("Annotation service property value missing for package #{pkg} in property #{CaRuby::Domain::Properties::ANN_SVCS_PROP}")
|
75
|
-
end
|
76
|
-
@pkg_svc_hash[pkg] = Annotation::AnnotationService.new(database, svc_nm, :anchor => anchor_class,
|
77
|
-
:integration_service => integration_service, :entity_manager => entity_manager)
|
78
|
-
logger.debug { "Annotator service #{anchor_class.qp} #{svc_nm} created for attributes #{signatures.pp_s(:single_line)}" }
|
79
|
-
end
|
80
|
-
end
|
81
|
-
end
|
19
|
+
# @param [String] name the service name
|
20
|
+
# @return [Annotation::AnnotationService] the annotation service
|
21
|
+
def create_annotation_service(name)
|
22
|
+
Annotation::AnnotationService.new(@database, name, :integration_service => @integration_service)
|
82
23
|
end
|
83
24
|
end
|
84
25
|
end
|