diff --git a/config/solr/property_search/enumsconfig.xml b/config/solr/property_search/enumsconfig.xml
new file mode 100644
index 00000000..72e7b7d3
--- /dev/null
+++ b/config/solr/property_search/enumsconfig.xml
@@ -0,0 +1,12 @@
+
+
+
+ ONTOLOGY
+ VALUE_SET_COLLECTION
+
+
+ ANNOTATION
+ DATATYPE
+ OBJECT
+
+
\ No newline at end of file
diff --git a/config/solr/property_search/mapping-ISOLatin1Accent.txt b/config/solr/property_search/mapping-ISOLatin1Accent.txt
new file mode 100644
index 00000000..ede77425
--- /dev/null
+++ b/config/solr/property_search/mapping-ISOLatin1Accent.txt
@@ -0,0 +1,246 @@
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# Syntax:
+# "source" => "target"
+# "source".length() > 0 (source cannot be empty.)
+# "target".length() >= 0 (target can be empty.)
+
+# example:
+# "À" => "A"
+# "\u00C0" => "A"
+# "\u00C0" => "\u0041"
+# "ß" => "ss"
+# "\t" => " "
+# "\n" => ""
+
+# À => A
+"\u00C0" => "A"
+
+# Á => A
+"\u00C1" => "A"
+
+# Â => A
+"\u00C2" => "A"
+
+# Ã => A
+"\u00C3" => "A"
+
+# Ä => A
+"\u00C4" => "A"
+
+# Å => A
+"\u00C5" => "A"
+
+# Æ => AE
+"\u00C6" => "AE"
+
+# Ç => C
+"\u00C7" => "C"
+
+# È => E
+"\u00C8" => "E"
+
+# É => E
+"\u00C9" => "E"
+
+# Ê => E
+"\u00CA" => "E"
+
+# Ë => E
+"\u00CB" => "E"
+
+# Ì => I
+"\u00CC" => "I"
+
+# Í => I
+"\u00CD" => "I"
+
+# Î => I
+"\u00CE" => "I"
+
+# Ï => I
+"\u00CF" => "I"
+
+# IJ => IJ
+"\u0132" => "IJ"
+
+# Ð => D
+"\u00D0" => "D"
+
+# Ñ => N
+"\u00D1" => "N"
+
+# Ò => O
+"\u00D2" => "O"
+
+# Ó => O
+"\u00D3" => "O"
+
+# Ô => O
+"\u00D4" => "O"
+
+# Õ => O
+"\u00D5" => "O"
+
+# Ö => O
+"\u00D6" => "O"
+
+# Ø => O
+"\u00D8" => "O"
+
+# Œ => OE
+"\u0152" => "OE"
+
+# Þ
+"\u00DE" => "TH"
+
+# Ù => U
+"\u00D9" => "U"
+
+# Ú => U
+"\u00DA" => "U"
+
+# Û => U
+"\u00DB" => "U"
+
+# Ü => U
+"\u00DC" => "U"
+
+# Ý => Y
+"\u00DD" => "Y"
+
+# Ÿ => Y
+"\u0178" => "Y"
+
+# à => a
+"\u00E0" => "a"
+
+# á => a
+"\u00E1" => "a"
+
+# â => a
+"\u00E2" => "a"
+
+# ã => a
+"\u00E3" => "a"
+
+# ä => a
+"\u00E4" => "a"
+
+# å => a
+"\u00E5" => "a"
+
+# æ => ae
+"\u00E6" => "ae"
+
+# ç => c
+"\u00E7" => "c"
+
+# è => e
+"\u00E8" => "e"
+
+# é => e
+"\u00E9" => "e"
+
+# ê => e
+"\u00EA" => "e"
+
+# ë => e
+"\u00EB" => "e"
+
+# ì => i
+"\u00EC" => "i"
+
+# í => i
+"\u00ED" => "i"
+
+# î => i
+"\u00EE" => "i"
+
+# ï => i
+"\u00EF" => "i"
+
+# ij => ij
+"\u0133" => "ij"
+
+# ð => d
+"\u00F0" => "d"
+
+# ñ => n
+"\u00F1" => "n"
+
+# ò => o
+"\u00F2" => "o"
+
+# ó => o
+"\u00F3" => "o"
+
+# ô => o
+"\u00F4" => "o"
+
+# õ => o
+"\u00F5" => "o"
+
+# ö => o
+"\u00F6" => "o"
+
+# ø => o
+"\u00F8" => "o"
+
+# œ => oe
+"\u0153" => "oe"
+
+# ß => ss
+"\u00DF" => "ss"
+
+# þ => th
+"\u00FE" => "th"
+
+# ù => u
+"\u00F9" => "u"
+
+# ú => u
+"\u00FA" => "u"
+
+# û => u
+"\u00FB" => "u"
+
+# ü => u
+"\u00FC" => "u"
+
+# ý => y
+"\u00FD" => "y"
+
+# ÿ => y
+"\u00FF" => "y"
+
+# ff => ff
+"\uFB00" => "ff"
+
+# fi => fi
+"\uFB01" => "fi"
+
+# fl => fl
+"\uFB02" => "fl"
+
+# ffi => ffi
+"\uFB03" => "ffi"
+
+# ffl => ffl
+"\uFB04" => "ffl"
+
+# ſt => ft
+"\uFB05" => "ft"
+
+# st => st
+"\uFB06" => "st"
diff --git a/config/solr/property_search/schema.xml b/config/solr/property_search/schema.xml
new file mode 100644
index 00000000..20824ea6
--- /dev/null
+++ b/config/solr/property_search/schema.xml
@@ -0,0 +1,1179 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ id
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/config/solr/property_search/solrconfig.xml b/config/solr/property_search/solrconfig.xml
new file mode 100644
index 00000000..771a0f32
--- /dev/null
+++ b/config/solr/property_search/solrconfig.xml
@@ -0,0 +1,1299 @@
+
+
+
+
+
+
+
+
+ 8.8.2
+
+
+
+
+
+
+
+
+
+
+ ${solr.data.dir:}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ${solr.lock.type:native}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ${solr.ulog.dir:}
+ ${solr.ulog.numVersionBuckets:65536}
+
+
+
+
+ ${solr.autoCommit.maxTime:15000}
+ false
+
+
+
+
+
+ ${solr.autoSoftCommit.maxTime:-1}
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ${solr.max.booleanClauses:500000}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ true
+
+
+
+
+
+ 20
+
+
+ 200
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ false
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ explicit
+ 10
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ explicit
+ json
+ true
+
+
+
+
+
+ _text_
+
+
+
+
+
+
+
+
+ text_general
+
+
+
+
+
+ default
+ _text_
+ solr.DirectSolrSpellChecker
+
+ internal
+
+ 0.5
+
+ 2
+
+ 1
+
+ 5
+
+ 4
+
+ 0.01
+
+
+
+
+
+
+
+
+
+
+
+ default
+ on
+ true
+ 10
+ 5
+ 5
+ true
+ true
+ 10
+ 5
+
+
+ spellcheck
+
+
+
+
+
+
+
+
+
+ true
+ false
+
+
+ terms
+
+
+
+
+
+
+
+
+
+
+ 100
+
+
+
+
+
+
+
+ 70
+
+ 0.5
+
+ [-\w ,/\n\"']{20,200}
+
+
+
+
+
+
+ ]]>
+ ]]>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ,,
+ ,,
+ ,,
+ ,,
+ ,]]>
+ ]]>
+
+
+
+
+
+ 10
+ .,!?
+
+
+
+
+
+
+ WORD
+
+
+ en
+ US
+
+
+
+
+
+
+
+
+
+
+
+ [^\w-\.]
+ _
+
+
+
+
+
+
+ yyyy-MM-dd['T'[HH:mm[:ss[.SSS]][z
+ yyyy-MM-dd['T'[HH:mm[:ss[,SSS]][z
+ yyyy-MM-dd HH:mm[:ss[.SSS]][z
+ yyyy-MM-dd HH:mm[:ss[,SSS]][z
+ [EEE, ]dd MMM yyyy HH:mm[:ss] z
+ EEEE, dd-MMM-yy HH:mm:ss z
+ EEE MMM ppd HH:mm:ss [z ]yyyy
+
+
+
+
+ java.lang.String
+ text_general
+
+ *_str
+ 256
+
+
+ true
+
+
+ java.lang.Boolean
+ booleans
+
+
+ java.util.Date
+ pdates
+
+
+ java.lang.Long
+ java.lang.Integer
+ plongs
+
+
+ java.lang.Number
+ pdoubles
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/plain; charset=UTF-8
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/config/solr/solr.xml b/config/solr/solr.xml
new file mode 100644
index 00000000..d9d089e4
--- /dev/null
+++ b/config/solr/solr.xml
@@ -0,0 +1,60 @@
+
+
+
+
+
+
+
+ ${solr.max.booleanClauses:500000}
+ ${solr.sharedLib:}
+ ${solr.allowPaths:}
+
+
+
+ ${host:}
+ ${solr.port.advertise:0}
+ ${hostContext:solr}
+
+ ${genericCoreNodeNames:true}
+
+ ${zkClientTimeout:30000}
+ ${distribUpdateSoTimeout:600000}
+ ${distribUpdateConnTimeout:60000}
+ ${zkCredentialsProvider:org.apache.solr.common.cloud.DefaultZkCredentialsProvider}
+ ${zkACLProvider:org.apache.solr.common.cloud.DefaultZkACLProvider}
+
+
+
+
+ ${socketTimeout:600000}
+ ${connTimeout:60000}
+ ${solr.shardsWhitelist:}
+
+
+
+
+
diff --git a/config/solr/term_search/enumsconfig.xml b/config/solr/term_search/enumsconfig.xml
new file mode 100644
index 00000000..72e7b7d3
--- /dev/null
+++ b/config/solr/term_search/enumsconfig.xml
@@ -0,0 +1,12 @@
+
+
+
+ ONTOLOGY
+ VALUE_SET_COLLECTION
+
+
+ ANNOTATION
+ DATATYPE
+ OBJECT
+
+
\ No newline at end of file
diff --git a/config/solr/term_search/mapping-ISOLatin1Accent.txt b/config/solr/term_search/mapping-ISOLatin1Accent.txt
new file mode 100644
index 00000000..ede77425
--- /dev/null
+++ b/config/solr/term_search/mapping-ISOLatin1Accent.txt
@@ -0,0 +1,246 @@
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# Syntax:
+# "source" => "target"
+# "source".length() > 0 (source cannot be empty.)
+# "target".length() >= 0 (target can be empty.)
+
+# example:
+# "À" => "A"
+# "\u00C0" => "A"
+# "\u00C0" => "\u0041"
+# "ß" => "ss"
+# "\t" => " "
+# "\n" => ""
+
+# À => A
+"\u00C0" => "A"
+
+# Á => A
+"\u00C1" => "A"
+
+# Â => A
+"\u00C2" => "A"
+
+# Ã => A
+"\u00C3" => "A"
+
+# Ä => A
+"\u00C4" => "A"
+
+# Å => A
+"\u00C5" => "A"
+
+# Æ => AE
+"\u00C6" => "AE"
+
+# Ç => C
+"\u00C7" => "C"
+
+# È => E
+"\u00C8" => "E"
+
+# É => E
+"\u00C9" => "E"
+
+# Ê => E
+"\u00CA" => "E"
+
+# Ë => E
+"\u00CB" => "E"
+
+# Ì => I
+"\u00CC" => "I"
+
+# Í => I
+"\u00CD" => "I"
+
+# Î => I
+"\u00CE" => "I"
+
+# Ï => I
+"\u00CF" => "I"
+
+# IJ => IJ
+"\u0132" => "IJ"
+
+# Ð => D
+"\u00D0" => "D"
+
+# Ñ => N
+"\u00D1" => "N"
+
+# Ò => O
+"\u00D2" => "O"
+
+# Ó => O
+"\u00D3" => "O"
+
+# Ô => O
+"\u00D4" => "O"
+
+# Õ => O
+"\u00D5" => "O"
+
+# Ö => O
+"\u00D6" => "O"
+
+# Ø => O
+"\u00D8" => "O"
+
+# Œ => OE
+"\u0152" => "OE"
+
+# Þ
+"\u00DE" => "TH"
+
+# Ù => U
+"\u00D9" => "U"
+
+# Ú => U
+"\u00DA" => "U"
+
+# Û => U
+"\u00DB" => "U"
+
+# Ü => U
+"\u00DC" => "U"
+
+# Ý => Y
+"\u00DD" => "Y"
+
+# Ÿ => Y
+"\u0178" => "Y"
+
+# à => a
+"\u00E0" => "a"
+
+# á => a
+"\u00E1" => "a"
+
+# â => a
+"\u00E2" => "a"
+
+# ã => a
+"\u00E3" => "a"
+
+# ä => a
+"\u00E4" => "a"
+
+# å => a
+"\u00E5" => "a"
+
+# æ => ae
+"\u00E6" => "ae"
+
+# ç => c
+"\u00E7" => "c"
+
+# è => e
+"\u00E8" => "e"
+
+# é => e
+"\u00E9" => "e"
+
+# ê => e
+"\u00EA" => "e"
+
+# ë => e
+"\u00EB" => "e"
+
+# ì => i
+"\u00EC" => "i"
+
+# í => i
+"\u00ED" => "i"
+
+# î => i
+"\u00EE" => "i"
+
+# ï => i
+"\u00EF" => "i"
+
+# ij => ij
+"\u0133" => "ij"
+
+# ð => d
+"\u00F0" => "d"
+
+# ñ => n
+"\u00F1" => "n"
+
+# ò => o
+"\u00F2" => "o"
+
+# ó => o
+"\u00F3" => "o"
+
+# ô => o
+"\u00F4" => "o"
+
+# õ => o
+"\u00F5" => "o"
+
+# ö => o
+"\u00F6" => "o"
+
+# ø => o
+"\u00F8" => "o"
+
+# œ => oe
+"\u0153" => "oe"
+
+# ß => ss
+"\u00DF" => "ss"
+
+# þ => th
+"\u00FE" => "th"
+
+# ù => u
+"\u00F9" => "u"
+
+# ú => u
+"\u00FA" => "u"
+
+# û => u
+"\u00FB" => "u"
+
+# ü => u
+"\u00FC" => "u"
+
+# ý => y
+"\u00FD" => "y"
+
+# ÿ => y
+"\u00FF" => "y"
+
+# ff => ff
+"\uFB00" => "ff"
+
+# fi => fi
+"\uFB01" => "fi"
+
+# fl => fl
+"\uFB02" => "fl"
+
+# ffi => ffi
+"\uFB03" => "ffi"
+
+# ffl => ffl
+"\uFB04" => "ffl"
+
+# ſt => ft
+"\uFB05" => "ft"
+
+# st => st
+"\uFB06" => "st"
diff --git a/config/solr/term_search/schema.xml b/config/solr/term_search/schema.xml
new file mode 100644
index 00000000..fa95e127
--- /dev/null
+++ b/config/solr/term_search/schema.xml
@@ -0,0 +1,1222 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ id
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/config/solr/term_search/solrconfig.xml b/config/solr/term_search/solrconfig.xml
new file mode 100644
index 00000000..771a0f32
--- /dev/null
+++ b/config/solr/term_search/solrconfig.xml
@@ -0,0 +1,1299 @@
+
+
+
+
+
+
+
+
+ 8.8.2
+
+
+
+
+
+
+
+
+
+
+ ${solr.data.dir:}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ${solr.lock.type:native}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ${solr.ulog.dir:}
+ ${solr.ulog.numVersionBuckets:65536}
+
+
+
+
+ ${solr.autoCommit.maxTime:15000}
+ false
+
+
+
+
+
+ ${solr.autoSoftCommit.maxTime:-1}
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ${solr.max.booleanClauses:500000}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ true
+
+
+
+
+
+ 20
+
+
+ 200
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ false
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ explicit
+ 10
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ explicit
+ json
+ true
+
+
+
+
+
+ _text_
+
+
+
+
+
+
+
+
+ text_general
+
+
+
+
+
+ default
+ _text_
+ solr.DirectSolrSpellChecker
+
+ internal
+
+ 0.5
+
+ 2
+
+ 1
+
+ 5
+
+ 4
+
+ 0.01
+
+
+
+
+
+
+
+
+
+
+
+ default
+ on
+ true
+ 10
+ 5
+ 5
+ true
+ true
+ 10
+ 5
+
+
+ spellcheck
+
+
+
+
+
+
+
+
+
+ true
+ false
+
+
+ terms
+
+
+
+
+
+
+
+
+
+
+ 100
+
+
+
+
+
+
+
+ 70
+
+ 0.5
+
+ [-\w ,/\n\"']{20,200}
+
+
+
+
+
+
+ ]]>
+ ]]>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ,,
+ ,,
+ ,,
+ ,,
+ ,]]>
+ ]]>
+
+
+
+
+
+ 10
+ .,!?
+
+
+
+
+
+
+ WORD
+
+
+ en
+ US
+
+
+
+
+
+
+
+
+
+
+
+ [^\w-\.]
+ _
+
+
+
+
+
+
+ yyyy-MM-dd['T'[HH:mm[:ss[.SSS]][z
+ yyyy-MM-dd['T'[HH:mm[:ss[,SSS]][z
+ yyyy-MM-dd HH:mm[:ss[.SSS]][z
+ yyyy-MM-dd HH:mm[:ss[,SSS]][z
+ [EEE, ]dd MMM yyyy HH:mm[:ss] z
+ EEEE, dd-MMM-yy HH:mm:ss z
+ EEE MMM ppd HH:mm:ss [z ]yyyy
+
+
+
+
+ java.lang.String
+ text_general
+
+ *_str
+ 256
+
+
+ true
+
+
+ java.lang.Boolean
+ booleans
+
+
+ java.util.Date
+ pdates
+
+
+ java.lang.Long
+ java.lang.Integer
+ plongs
+
+
+ java.lang.Number
+ pdoubles
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/plain; charset=UTF-8
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/controllers/agents_controller.rb b/controllers/agents_controller.rb
new file mode 100644
index 00000000..87572e99
--- /dev/null
+++ b/controllers/agents_controller.rb
@@ -0,0 +1,145 @@
+class AgentsController < ApplicationController
+
+ %w[/agents /Agents].each do |namespace|
+ namespace namespace do
+ # Display all agents
+ get do
+ check_last_modified_collection(LinkedData::Models::Agent)
+ query = LinkedData::Models::Agent.where
+ query = apply_filters(LinkedData::Models::Agent, query)
+ query = query.include(LinkedData::Models::Agent.goo_attrs_to_load(includes_param))
+ if page?
+ page, size = page_params
+ agents = query.page(page, size).all
+ else
+ agents = query.to_a
+ end
+ reply agents
+ end
+
+ # Display a single agent
+ get '/:id' do
+ check_last_modified_collection(LinkedData::Models::Agent)
+ id = params["id"]
+ agent = LinkedData::Models::Agent.find(id).include(LinkedData::Models::Agent.goo_attrs_to_load(includes_param)).first
+ error 404, "Agent #{id} not found" if agent.nil?
+ reply 200, agent
+ end
+
+ # Create a agent with the given acronym
+ post do
+ reply 201, create_new_agent
+ end
+
+ # Create a agent with the given acronym
+ put '/:acronym' do
+ reply 201, create_new_agent
+ end
+
+ # Update an existing submission of a agent
+ patch '/:id' do
+ acronym = params["id"]
+ agent = LinkedData::Models::Agent.find(acronym).include(LinkedData::Models::Agent.attributes).first
+
+ if agent.nil?
+ error 400, "Agent does not exist, please create using HTTP PUT before modifying"
+ else
+ agent = update_agent(agent, params)
+
+ error 400, agent.errors unless agent.errors.empty?
+ end
+ halt 204
+ end
+
+ # Delete a agent
+ delete '/:id' do
+ agent = LinkedData::Models::Agent.find(params["id"]).first
+ agent.delete
+ halt 204
+ end
+
+ private
+
+ def update_identifiers(identifiers)
+ Array(identifiers).map do |i|
+ next nil if i.empty?
+
+ id = i["id"] || LinkedData::Models::AgentIdentifier.generate_identifier(i['notation'], i['schemaAgency'])
+ identifier = LinkedData::Models::AgentIdentifier.find(RDF::URI.new(id)).first
+
+ if identifier
+ identifier.bring_remaining
+ else
+ identifier = LinkedData::Models::AgentIdentifier.new
+ end
+
+ i.delete "id"
+
+ next identifier if i.keys.size.zero?
+
+ populate_from_params(identifier, i)
+
+ if identifier.valid?
+ identifier.save
+ else
+ error 400, identifier.errors
+ end
+ identifier
+ end.compact
+ end
+
+ def update_affiliations(affiliations)
+ Array(affiliations).map do |aff|
+ affiliation = aff["id"] ? LinkedData::Models::Agent.find(RDF::URI.new(aff["id"])).first : nil
+
+ if affiliation
+ affiliation.bring_remaining
+ affiliation.identifiers.each{|i| i.bring_remaining}
+ end
+
+ next affiliation if aff.keys.size.eql?(1) && aff["id"]
+
+ if affiliation
+ affiliation = update_agent(affiliation, aff)
+ else
+ affiliation = create_new_agent(aff["id"], aff)
+ end
+
+ error 400, affiliation.errors unless affiliation.errors.empty?
+
+ affiliation
+ end
+ end
+
+ def create_new_agent (id = @params['id'], params = @params)
+ agent = nil
+ agent = LinkedData::Models::Agent.find(id).include(LinkedData::Models::Agent.goo_attrs_to_load(includes_param)).first if id
+
+ if agent.nil?
+ agent = update_agent(LinkedData::Models::Agent.new, params)
+ error 400, agent.errors unless agent.errors.empty?
+
+ return agent
+ else
+ error 400, "Agent exists, please use HTTP PATCH to update"
+ end
+ end
+
+ def update_agent(agent, params)
+ return agent unless agent
+
+ identifiers = params.delete "identifiers"
+ affiliations = params.delete "affiliations"
+ params.delete "id"
+ populate_from_params(agent, params)
+ agent.identifiers = update_identifiers(identifiers)
+ agent.affiliations = update_affiliations(affiliations)
+
+ agent.save if agent.valid?
+ return agent
+ end
+
+ end
+ end
+
+end
\ No newline at end of file
diff --git a/helpers/metadata_helper.rb b/helpers/metadata_helper.rb
index db61c414..2c5d7182 100644
--- a/helpers/metadata_helper.rb
+++ b/helpers/metadata_helper.rb
@@ -64,15 +64,23 @@ def klass_metadata(klass, type)
# Get display from the metadata
if klass.attribute_settings(attr)[:display].nil?
- attr_settings[:display] = "no"
+ attr_settings[:category] = "no"
else
- attr_settings[:display] = klass.attribute_settings(attr)[:display]
+ attr_settings[:category] = klass.attribute_settings(attr)[:display]
end
- if !klass.attribute_settings(attr)[:helpText].nil?
+ unless klass.attribute_settings(attr)[:helpText].nil?
attr_settings[:helpText] = klass.attribute_settings(attr)[:helpText]
end
+ unless klass.attribute_settings(attr)[:description].nil?
+ attr_settings[:description] = klass.attribute_settings(attr)[:description]
+ end
+
+ unless klass.attribute_settings(attr)[:example].nil?
+ attr_settings[:example] = klass.attribute_settings(attr)[:example]
+ end
+
attr_settings[:@context] = {
"@vocab" => "#{id_url_prefix}metadata/"
}
diff --git a/test/controllers/test_agents_controller.rb b/test/controllers/test_agents_controller.rb
new file mode 100644
index 00000000..ef0e5c47
--- /dev/null
+++ b/test/controllers/test_agents_controller.rb
@@ -0,0 +1,225 @@
+require_relative '../test_case'
+require "multi_json"
+
+class TestAgentsController < TestCase
+
+ def setup
+
+ @number_of_organizations = 6
+
+
+ @test_agents = 8.times.map do |i|
+ type = i < @number_of_organizations ? 'organization' : 'person'
+ _agent_data(type: type)
+ end
+ @agents = []
+ 2.times.map do
+ agents_tmp = [ _agent_data(type: 'organization'), _agent_data(type: 'organization'), _agent_data(type: 'person')]
+ agent = agents_tmp.last
+ agent[:affiliations] = [agents_tmp[0].stringify_keys, agents_tmp[1].stringify_keys]
+ _test_agent_creation(agent)
+ @agents = @agents + agents_tmp
+ end
+ end
+
+ def teardown
+ # Delete groups
+ _delete_agents
+ end
+
+ def test_all_agents
+ get '/agents'
+ assert last_response.ok?
+
+ created_agents = MultiJson.load(last_response.body)
+
+ @agents.each do |agent|
+ created_agent = created_agents.select{|x| x["name"].eql?(agent[:name])}.first
+ refute_nil created_agent
+ assert_equal agent[:name], created_agent["name"]
+ assert_equal agent[:identifiers].size, created_agent["identifiers"].size
+ assert_equal agent[:identifiers].map{|x| x[:notation]}.sort, created_agent["identifiers"].map{|x| x['notation']}.sort
+ assert_equal agent[:affiliations].size, created_agent["affiliations"].size
+ assert_equal agent[:affiliations].map{|x| x["name"]}.sort, created_agent["affiliations"].map{|x| x['name']}.sort
+
+ end
+ end
+
+ def test_single_agent
+ @agents.each do |agent|
+ agent_obj = _find_agent(agent['name'])
+ get "/agents/#{agent_obj.id.to_s.split('/').last}"
+ assert last_response.ok?
+ agent_found = MultiJson.load(last_response.body)
+ assert_equal agent_obj.id.to_s, agent_found["id"]
+ end
+ end
+
+ def test_create_new_agent
+
+ ## Create Agent of type affiliation with no parent affiliation
+ agent = @test_agents[0]
+ created_agent = _test_agent_creation(agent)
+
+ ## Create Agent of type affiliation with an extent parent affiliation
+
+ agent = @test_agents[1]
+ agent[:affiliations] = [created_agent]
+
+ created_agent = _test_agent_creation(agent)
+
+ ## Create Agent of type affiliation with an no extent parent affiliation
+ agent = @test_agents[3]
+ agent[:affiliations] = [created_agent, @test_agents[2].stringify_keys]
+ created_agent = _test_agent_creation(agent)
+
+ ## Create Agent of type Person with an extent affiliations
+
+ agent = @test_agents[6]
+ agent[:affiliations] = created_agent["affiliations"]
+ _test_agent_creation(agent)
+
+ ## Create Agent of type Person with no extent affiliations
+
+ agent = @test_agents[7]
+ agent[:affiliations] = [@test_agents[4].stringify_keys, @test_agents[5].stringify_keys]
+ _test_agent_creation(agent)
+
+ @agents = @agents + @test_agents
+ end
+
+
+ def test_new_agent_no_valid
+ agents_tmp = [ _agent_data(type: 'organization'), _agent_data(type: 'person'), _agent_data(type: 'person')]
+ agent = agents_tmp.last
+ agent[:affiliations] = [agents_tmp[0].stringify_keys, agents_tmp[1].stringify_keys]
+ post "/agents", MultiJson.dump(agent), "CONTENT_TYPE" => "application/json"
+ assert last_response.status == 400
+ end
+
+ def test_update_patch_agent
+
+ agents = [ _agent_data(type: 'organization'), _agent_data(type: 'organization'), _agent_data(type: 'person')]
+ agent = agents.last
+ agent[:affiliations] = [agents[0].stringify_keys, agents[1].stringify_keys]
+ agent = _test_agent_creation(agent)
+ @agents = @agents + agents
+ agent = LinkedData::Models::Agent.find(agent['id'].split('/').last).first
+ agent.bring_remaining
+
+
+ ## update identifiers
+ agent.identifiers.each{|i| i.bring_remaining}
+ new_identifiers = []
+ ## update an existent identifier
+ new_identifiers[0] = {
+ id: agent.identifiers[0].id.to_s,
+ schemaAgency: 'TEST ' + agent.identifiers[0].notation
+ }
+
+ new_identifiers[1] = {
+ id: agent.identifiers[1].id.to_s
+ }
+
+ ## update affiliation
+ agent.affiliations.each{|aff| aff.bring_remaining}
+ new_affiliations = []
+ ## update an existent affiliation
+ new_affiliations[0] = {
+ name: 'TEST new of ' + agent.affiliations[0].name,
+ id: agent.affiliations[0].id.to_s
+ }
+ ## create a new affiliation
+ new_affiliations[1] = _agent_data(type: 'organization')
+ new_affiliations[1][:name] = 'new affiliation'
+
+ new_values = {
+ name: 'new name ',
+ identifiers: new_identifiers,
+ affiliations: new_affiliations
+ }
+
+ patch "/agents/#{agent.id.split('/').last}", MultiJson.dump(new_values), "CONTENT_TYPE" => "application/json"
+ assert last_response.status == 204
+
+ get "/agents/#{agent.id.split('/').last}"
+ new_agent = MultiJson.load(last_response.body)
+ assert_equal 'new name ', new_agent["name"]
+
+ assert_equal new_identifiers.size, new_agent["identifiers"].size
+ assert_equal new_identifiers[0][:schemaAgency], new_agent["identifiers"].select{|x| x["id"].eql?(agent.identifiers[0].id.to_s)}.first["schemaAgency"]
+ assert_equal agent.identifiers[1].schemaAgency, new_agent["identifiers"].select{|x| x["id"].eql?(agent.identifiers[1].id.to_s)}.first["schemaAgency"]
+
+ assert_equal new_affiliations.size, new_agent["affiliations"].size
+ assert_equal new_affiliations[0][:name], new_agent["affiliations"].select{|x| x["id"].eql?(agent.affiliations[0].id.to_s)}.first["name"]
+ assert_nil new_agent["affiliations"].select{|x| x["id"].eql?(agent.affiliations[1].id.to_s)}.first
+ assert_equal new_affiliations[1][:name], new_agent["affiliations"].reject{|x| x["id"].eql?(agent.affiliations[0].id.to_s)}.first["name"]
+ end
+
+ def test_delete_agent
+ agent = @agents.delete_at(0)
+ agent_obj = _find_agent(agent['name'])
+ id = agent_obj.id.to_s.split('/').last
+ delete "/agents/#{id}"
+ assert last_response.status == 204
+
+ get "/agents/#{id}"
+ assert last_response.status == 404
+ end
+
+ private
+ def _agent_data(type: 'organization')
+ schema_agencies = LinkedData::Models::AgentIdentifier::IDENTIFIER_SCHEMES.keys
+ users = LinkedData::Models::User.all
+ users = [LinkedData::Models::User.new(username: "tim", email: "tim@example.org", password: "password").save] if users.empty?
+ test_identifiers = 5.times.map { |i| { notation: rand.to_s[2..11], schemaAgency: schema_agencies.sample.to_s } }
+ user = users.sample.id.to_s
+
+ i = rand.to_s[2..11]
+ return {
+ agentType: type,
+ name: "name #{i}",
+ homepage: "home page #{i}",
+ acronym: "acronym #{i}",
+ email: "email_#{i}@test.com",
+ identifiers: test_identifiers.sample(2).map { |x| x.merge({ creator: user }) },
+ affiliations: [],
+ creator: user
+ }
+ end
+
+ def _find_agent(name)
+ LinkedData::Models::Agent.where(name: name).first
+ end
+
+ def _delete_agents
+ @agents.each do |agent|
+ test_cat = _find_agent(agent[:name])
+ next if test_cat.nil?
+
+ test_cat.bring :identifiers
+ test_cat.identifiers.each { |i| i.delete }
+ test_cat.delete
+ end
+ end
+
+ def _test_agent_creation(agent)
+ post "/agents", MultiJson.dump(agent), "CONTENT_TYPE" => "application/json"
+
+ assert last_response.status == 201
+ created_agent = MultiJson.load(last_response.body)
+ assert created_agent["name"].eql?(agent[:name])
+
+ get "/agents/#{created_agent['id'].split('/').last}"
+ assert last_response.ok?
+
+ created_agent = MultiJson.load(last_response.body)
+ assert_equal agent[:name], created_agent["name"]
+ assert_equal agent[:identifiers].size, created_agent["identifiers"].size
+ assert_equal agent[:identifiers].map { |x| x[:notation] }.sort, created_agent["identifiers"].map { |x| x['notation'] }.sort
+
+ assert_equal agent[:affiliations].size, created_agent["affiliations"].size
+ assert_equal agent[:affiliations].map { |x| x["name"] }.sort, created_agent["affiliations"].map { |x| x['name'] }.sort
+ created_agent
+ end
+end
\ No newline at end of file
diff --git a/test/controllers/test_annotator_controller.rb b/test/controllers/test_annotator_controller.rb
index ffa65a97..47f45f40 100644
--- a/test/controllers/test_annotator_controller.rb
+++ b/test/controllers/test_annotator_controller.rb
@@ -260,16 +260,16 @@ def test_default_properties_output
assert last_response.ok?
annotations = MultiJson.load(last_response.body)
assert_equal 9, annotations.length
- annotations.sort! { |a,b| a["annotatedClass"]["prefLabel"].downcase <=> b["annotatedClass"]["prefLabel"].downcase }
+ annotations.sort! { |a,b| a["annotatedClass"]["prefLabel"].first.downcase <=> b["annotatedClass"]["prefLabel"].first.downcase }
assert_equal "http://bioontology.org/ontologies/BiomedicalResourceOntology.owl#Aggregate_Human_Data", annotations.first["annotatedClass"]["@id"]
- assert_equal "Aggregate Human Data", annotations.first["annotatedClass"]["prefLabel"]
+ assert_equal "Aggregate Human Data", Array(annotations.first["annotatedClass"]["prefLabel"]).first
params = {text: text, include: "prefLabel,definition"}
get "/annotator", params
assert last_response.ok?
annotations = MultiJson.load(last_response.body)
assert_equal 9, annotations.length
- annotations.sort! { |a,b| a["annotatedClass"]["prefLabel"].downcase <=> b["annotatedClass"]["prefLabel"].downcase }
+ annotations.sort! { |a,b| Array(a["annotatedClass"]["prefLabel"]).first.downcase <=> Array(b["annotatedClass"]["prefLabel"]).first.downcase }
assert_equal "http://bioontology.org/ontologies/BiomedicalResourceOntology.owl#Aggregate_Human_Data", annotations.first["annotatedClass"]["@id"]
assert_equal ["A resource that provides data from clinical care that comprises combined data from multiple individual human subjects."], annotations.first["annotatedClass"]["definition"]
end
diff --git a/test/controllers/test_mappings_controller.rb b/test/controllers/test_mappings_controller.rb
index 52c3975d..cff52225 100644
--- a/test/controllers/test_mappings_controller.rb
+++ b/test/controllers/test_mappings_controller.rb
@@ -245,7 +245,7 @@ def mappings_with_display
get "/ontologies/#{ontology}/mappings?pagesize=#{pagesize}&page=#{page}&display=prefLabel"
assert last_response.ok?
mappings = MultiJson.load(last_response.body)
- assert mappings["collection"].all? { |m| m["classes"].all? { |c| c["prefLabel"].is_a?(String) && c["prefLabel"].length > 0 } }
+ assert mappings["collection"].all? { |m| m["classes"].all? { |c| c["prefLabel"].first.is_a?(String) && c["prefLabel"].first.length > 0 } }
def_count = 0
next_page = 1