2 * Retrieve, cache, and query MARC tag tables
4 angular.module('egCoreMod')
6 ['$q', 'egCore', 'egAuth',
7 function($q, egCore, egAuth) {
10 defaultTagTableSelector : {
11 marcFormat : 'marc21',
12 marcRecordType : 'biblio',
17 authority_control_set : {
22 // allow 'bre' and 'biblio' to be synonyms, etc.
23 service.normalizeRecordType = function(recordType) {
24 if (recordType === 'sre') {
26 } else if (recordType === 'bre') {
28 } else if (recordType === 'are') {
35 service.loadTagTable = function(args) {
36 var fields = service.defaultTagTableSelector;
38 if (args.marcFormat) {
39 fields.marcFormat = args.marcFormat;
41 if (args.marcRecordType) {
42 fields.marcRecordType = service.normalizeRecordType(args.marcRecordType);
45 var tt_key = 'current_tag_table_' + fields.marcFormat + '_' +
46 fields.marcRecordType;
47 egCore.hatch.getItem(tt_key).then(function(tt) {
51 service.loadRemoteTagTable(fields, tt_key);
56 service.fetchFFPosTable = function(rtype) {
57 var deferred = $q.defer();
59 var hatch_pos_key = 'FFPosTable_'+rtype;
61 egCore.hatch.getItem(hatch_pos_key).then(function(cached_table) {
63 service.ff_pos_map[rtype] = cached_table;
64 deferred.resolve(cached_table);
68 egCore.net.request( // First, get the list of FFs (minus 006)
70 'open-ils.fielder.cmfpm.atomic',
71 { query : { tag : { '!=' : '006' } } }
72 ).then(function (data) {
73 service.ff_pos_map[rtype] = data;
74 egCore.hatch.setItem(hatch_pos_key, data);
75 deferred.resolve(data);
80 return deferred.promise;
83 service.fetchFFValueTable = function(rtype) {
84 var deferred = $q.defer();
86 var hatch_value_key = 'FFValueTable_'+rtype;
88 egCore.hatch.getItem(hatch_value_key).then(function(cached_table) {
90 service.ff_value_map[rtype] = cached_table;
91 deferred.resolve(cached_table);
97 'open-ils.cat.biblio.fixed_field_values.by_rec_type',
99 ).then(function (data) {
100 service.ff_value_map[rtype] = data;
101 egCore.hatch.setItem(hatch_value_key, data);
102 deferred.resolve(data);
107 return deferred.promise;
110 service.loadRemoteTagTable = function(fields, tt_key) {
113 'open-ils.cat.tag_table.all.retrieve.local',
114 egAuth.token(), fields.marcFormat, fields.marcRecordType
117 egCore.hatch.setItem(tt_key, service.fields);
119 function (err) { console.err('error fetch tag table: ' + err) },
122 service.fields[field.tag] = field;
127 service.getFieldTags = function() {
129 angular.forEach(service.fields, function(value, key) {
132 label: key + ': ' + value.name
138 service.getSubfieldCodes = function(tag) {
141 if (!service.fields[tag]) return;
142 angular.forEach(service.fields[tag].subfields, function(value) {
145 label: value.code + ': ' + value.description
151 service.getSubfieldValues = function(tag, sf_code) {
153 if (!tag) return list;
154 if (!service.fields[tag]) return;
155 if (!service.fields[tag]) return;
156 angular.forEach(service.fields[tag].subfields, function(sf) {
157 if (sf.code == sf_code && sf.hasOwnProperty('value_list')) {
158 angular.forEach(sf.value_list, function(value) {
159 var label = (value.code == value.description) ?
161 value.code + ': ' + value.description;
172 service.getIndicatorValues = function(tag, pos) {
174 if (!tag) return list;
175 if (!service.fields[tag]) return;
176 if (!service.fields[tag]["ind" + pos]) return;
177 angular.forEach(service.fields[tag]["ind" + pos], function(value) {
180 label: value.code + ': ' + value.description
186 service.authorityControlSet = function (kwargs) {
188 kwargs = kwargs || {};
190 this._fetch_class = function(hint, cache_key) {
191 return egCore.pcrud.retrieveAll(hint, {}, {atomic : true}).then(
193 egCore.env.absorbList(list, hint);
194 service.authority_control_set[cache_key] = list;
199 this._fetch = function(cmap) {
200 var deferred = $q.defer();
202 for (var hint in cmap) {
203 promises.push(this._fetch_class(hint, cmap[hint]));
205 $q.all(promises).then(function() {
208 return deferred.promise;
211 this._parse = function() {
212 service.authority_control_set._browse_axis_by_code = {};
213 service.authority_control_set._browse_axis_list.forEach(function (ba) {
215 service.authority_control_set._browse_field_map_list.filter(
216 function (m) { return m.axis() == ba.code() }
219 service.authority_control_set._browse_axis_by_code[ba.code()] = ba;
222 // loop over each acs
223 service.authority_control_set._control_set_list.forEach(function (cs) {
224 service.authority_control_set._controlsets[''+cs.id()] = {
227 description : cs.description(),
228 authority_tag_map : {},
234 // grab the authority fields
235 var acsaf_list = service.authority_control_set._authority_field_list.filter(
236 function (af) { return af.control_set() == cs.id() }
239 var at_list = service.authority_control_set._thesaurus_list.filter(
240 function (at) { return at.control_set() == cs.id() }
243 service.authority_control_set._controlsets[''+cs.id()].raw.authority_fields( acsaf_list );
244 service.authority_control_set._controlsets[''+cs.id()].raw.thesauri( at_list );
246 // and loop over each
247 acsaf_list.forEach(function (csaf) {
250 // link the main entry if we're subordinate
251 if (csaf.main_entry()) {
253 acsaf_list.filter(function (x) {
254 return x.id() == csaf.main_entry();
259 // link the sub entries if we're main
261 acsaf_list.filter(function (x) {
262 return x.main_entry() == csaf.id();
267 var acsbf_list = service.authority_control_set._bib_field_list.filter(
268 function (b) { return b.authority_field() == csaf.id() }
270 csaf.bib_fields( acsbf_list );
272 service.authority_control_set._controlsets[''+cs.id()].bib_fields = [].concat(
273 service.authority_control_set._controlsets[''+cs.id()].bib_fields,
277 acsbf_list.forEach(function (csbf) {
278 // link the authority field to the bib field
279 if (csbf.authority_field()) {
280 csbf.authority_field(
281 acsaf_list.filter(function (x) {
282 return x.id() == csbf.authority_field();
289 service.authority_control_set._browse_axis_list.forEach(
292 function (m) { return m.field() == csaf.id() }
294 function (fm) { fm.field( csaf ); csaf.axis_maps().push( fm ) } // and set the field
301 // build the authority_tag_map
302 service.authority_control_set._controlsets[''+cs.id()].bib_fields.forEach(function (bf) {
304 if (!service.authority_control_set._controlsets[''+cs.id()].control_map[bf.tag()])
305 service.authority_control_set._controlsets[''+cs.id()].control_map[bf.tag()] = {};
307 bf.authority_field().sf_list().split('').forEach(function (sf_code) {
309 if (!service.authority_control_set._controlsets[''+cs.id()].control_map[bf.tag()][sf_code])
310 service.authority_control_set._controlsets[''+cs.id()].control_map[bf.tag()][sf_code] = {};
312 service.authority_control_set._controlsets[''+cs.id()].control_map[bf.tag()][sf_code][bf.authority_field().tag()] = sf_code;
318 if (this.controlSetList().length > 0)
319 delete service.authority_control_set._controlsets['-1'];
323 this.controlSetId = function (x) {
324 if (x) this._controlset = ''+x;
325 return this._controlset;
328 this.controlSetList = function () {
330 for (var i in service.authority_control_set._controlsets) {
337 if (!service.authority_control_set._remote_loaded) {
339 // TODO -- push the raw tree into the oils cache for later reuse
341 // fetch everything up front...
344 "acs": "_control_set_list",
345 "at": "_thesaurus_list",
346 "acsaf": "_authority_field_list",
347 "acsbf": "_bib_field_list",
348 "aba": "_browse_axis_list",
349 "abaafm": "_browse_field_map_list"
351 service.authority_control_set._remote_loaded = true;
356 this.controlSet = function (x) {
357 return service.authority_control_set._controlsets[''+this.controlSetId(x)];
360 this.controlSetByThesaurusCode = function (x) {
361 var thes = service.authority_control_set._thesaurus_list.filter(
362 function (at) { return at.code() == x }
365 return this.controlSet(thes.control_set());
368 this.browseAxisByCode = function(code) {
369 return service.authority_control_set._browse_axis_by_code[code];
372 this.bibFieldByTag = function (x) {
374 return me.controlSet().bib_fields.filter(
375 function (bf) { if (bf.tag() == x) return true }
379 this.bibFields = function (x) {
380 return this.controlSet(x).bib_fields;
383 this.bibFieldBrowseAxes = function (t) {
385 for (var bcode in service.authority_control_set._browse_axis_by_code) {
386 service.authority_control_set._browse_axis_by_code[bcode].maps().forEach(
388 if (m.field().bib_fields().filter(
389 function (b) { return b.tag() == t }
398 this.authorityFields = function (x) {
399 return this.controlSet(x).raw.authority_fields();
402 this.thesauri = function (x) {
403 return this.controlSet(x).raw.thesauri();
406 this.findControlSetsForTag = function (tag) {
408 var old_acs = this.controlSetId();
409 var acs_list = me.controlSetList().filter(
410 function(acs_id) { return (me.controlSet(acs_id).control_map[tag]) }
412 this.controlSetId(old_acs);
416 this.findControlSetsForAuthorityTag = function (tag) {
418 var old_acs = this.controlSetId();
420 var acs_list = me.controlSetList().filter(
422 var a = me.controlSet(acs_id);
423 for (var btag in a.control_map) {
424 for (var sf in a.control_map[btag]) {
425 if (a.control_map[btag][sf][tag]) return true;
431 this.controlSetId(old_acs);
435 this.bibToAuthority = function (field) {
436 var b_field = this.bibFieldByTag(field.tag);
438 if (b_field) { // construct an marc authority record
439 var af = b_field.authority_field();
442 for (var i = 0; i < field.subfields.length; i++) {
443 if (af.sf_list().indexOf(field.subfields[i][0]) > -1) {
444 sflist.push(field.subfields[i]);
448 var m = new MARC21.Record ({rtype:'AUT'});
458 return m.toXmlString();
464 this.bibToAuthorities = function (field) {
468 var old_acs = this.controlSetId();
469 me.controlSetList().forEach(
471 var acs = me.controlSet(acs_id);
472 var x = me.bibToAuthority(field);
473 if (x) { var foo = {}; foo[acs_id] = x; auth_list.push(foo); }
476 this.controlSetId(old_acs);
481 // This should not be used in an angular world. Instead, the call
482 // to open-ils.search.authority.simple_heading.from_xml.batch.atomic should
483 // be performed by the code that wants to find matching authorities.
484 this.findMatchingAuthorities = function (field) {
485 return fieldmapper.standardRequest(
486 [ 'open-ils.search', 'open-ils.search.authority.simple_heading.from_xml.batch.atomic' ],
487 this.bibToAuthorities(field)
491 if (kwargs.controlSet) {
492 this.controlSetId( kwargs.controlSet );
494 this.controlSetId( this.controlSetList().sort(function(a,b){return (a - b)}) );