]> git.evergreen-ils.org Git - working/Evergreen.git/blob - Open-ILS/web/js/dojo/MARC/Record.js
Add some logic for fetching stored controlsets and switching amongst them
[working/Evergreen.git] / Open-ILS / web / js / dojo / MARC / Record.js
1 /* ---------------------------------------------------------------------------
2  * Copyright (C) 2009  Equinox Software, Inc.
3  * Mike Rylander <miker@esilibrary.com>
4  *
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU General Public License
7  * as published by the Free Software Foundation; either version 2
8  * of the License, or (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  * ---------------------------------------------------------------------------
15  */
16
17 if(!dojo._hasResource["MARC.Record"]) {
18
19     dojo.require('dojox.xml.parser');
20     dojo.require('MARC.Field');
21
22     dojo._hasResource["MARC.Record"] = true;
23     dojo.provide("MARC.Record");
24     dojo.declare('MARC.Record', null, {
25
26         delimiter : '\u2021', // default subfield delimiter
27
28         constructor : function(kwargs) {
29             this.fields = [];
30             this.leader = '00000cam a2200205Ka 4500';
31
32             if (kwargs.delimiter) this.delimiter = kwargs.delimiter;
33             if (kwargs.onLoad) this.onLoad = kwargs.onLoad;
34             if (kwargs.url) {
35                 this.fromXmlURL(kwargs.url);
36             } else if (kwargs.marcxml) {
37                 this.fromXmlString(kwargs.marcxml);
38                 if (this.onLoad) this.onLoad();
39             } else if (kwargs.xml) {
40                 this.fromXmlDocument(kwargs.xml);
41                 if (this.onLoad) this.onLoad();
42             } else if (kwargs.marcbreaker) {
43                 this.fromBreaker(kwargs.marcbreaker);
44                 if (this.onLoad) this.onLoad();
45             }
46         },
47
48         title : function () { return this.subfield('245','a') },
49
50         field : function (spec) {
51             var list = dojo.filter( this.fields, function (f) {
52                 if (f.tag.match(spec)) return true;
53                 return false;
54             });
55
56             if (list.length == 1) return list[0];
57             return list;
58         },
59
60         subfield : function (spec, code) {
61             var f = this.field(spec);
62             if (dojo.isArray(f)) f = f[0];
63             return f.subfield(code)
64         },
65
66         appendFields : function () {
67             var me = this;
68             dojo.forEach( arguments, function (f) { me.fields.push( f ) } );
69         },
70
71         deleteField : function (f) { return this.deleteFields(f) },
72
73         insertOrderedFields : function () {
74             var me = this;
75             for (var i = 0; i < arguments.length; i++) {
76                 var f = arguments[i];
77                 var done = false;
78                 for (var j = 0; j < this.fields.length; j++) {
79                     if (f.tag < this.fields[j].tag) {
80                         this.insertFieldsBefore(this.fields[j], f);
81                         done = true;
82                         break;
83                     }
84                 }
85                 if (!done) this.appendFields(f);
86             }
87         },
88
89         insertFieldsBefore : function (target) {
90             var args = Array.prototype.slice.call(arguments);
91             args.splice(0,1);
92             var me = this;
93             for (var j = 0; j < this.fields.length; j++) {
94                 if (target === this.fields[j]) {
95                     j--;
96                     dojo.forEach( args, function (f) {
97                         me.fields.splice(j++,0,f);
98                     });
99                     break;
100                 }
101             }
102         },
103
104         insertFieldsAfter : function (target) {
105             var args = Array.prototype.slice.call(arguments);
106             args.splice(0,1);
107             var me = this;
108             for (var j = 0; j < this.fields.length; j++) {
109                 if (target === this.fields[j]) {
110                     dojo.forEach( args, function (f) {
111                         me.fields.splice(j++,0,f);
112                     });
113                     break;
114                 }
115             }
116         },
117
118         deleteFields : function () {
119             var me = this;
120             var counter = 0;
121             for ( var i in arguments ) {
122                 var f = arguments[i];
123                 for (var j = 0; j < me.fields.length; j++) {
124                     if (f === me.fields[j]) {
125                         me.fields[j].record = null;
126                         me.fields.splice(j,0);
127                         counter++
128                         break;
129                     }
130                 }
131             }
132             return counter;
133         },
134
135         clone : function () { return dojo.clone(this) },
136
137         fromXmlURL : function (url) {
138             this.ready   = false;
139             var me = this;
140             dojo.xhrGet({
141                 url     : url,
142                 sync    : true,
143                 handleAs: 'xml',
144                 load    : function (mxml) {
145                     me.fromXmlDocument(dojo.query('record', mxml)[0]);
146                     me.ready = true;
147                     if (me.onLoad) me.onLoad();
148                 }
149             });
150         },
151
152         fromXmlString : function (mxml) {
153                 return this.fromXmlDocument( dojox.xml.parser.parse( mxml ) );
154         },
155
156         fromXmlDocument : function (mxml) {
157             var me = this;
158             me.leader = dojox.xml.parser.textContent(dojo.query('leader', mxml)[0]) || '00000cam a2200205Ka 4500';
159
160             dojo.forEach( dojo.query('controlfield', mxml), function (cf) {
161                 me.fields.push(
162                     new MARC.Field({
163                           record : me,
164                           tag    : cf.getAttribute('tag'),
165                           data   : dojox.xml.parser.textContent(cf)
166                     })
167                 )
168             });
169
170             dojo.forEach( dojo.query('datafield', mxml), function (df) {
171                 me.fields.push(
172                     new MARC.Field({
173                         record    : me,
174                         tag       : df.getAttribute('tag'),
175                         ind1      : df.getAttribute('ind1'),
176                         ind2      : df.getAttribute('ind2'),
177                         subfields : dojo.map(
178                             dojo.query('subfield', df),
179                             function (sf) {
180                                 return [ sf.getAttribute('code'), dojox.xml.parser.textContent(sf) ];
181                             }
182                         )
183                     })
184                 )
185             });
186
187             return this;
188         },
189
190         toXmlDocument : function () {
191
192             var doc = dojox.xml.parser.parse('<record xmlns="http://www.loc.gov/MARC21/slim"/>');
193             var rec_node = dojo.query('record', doc)[0];
194
195             var ldr = doc.createElementNS('http://www.loc.gov/MARC21/slim', 'leader');
196             dojox.xml.parser.textContent(ldr, this.leader);
197             rec_node.appendChild( ldr );
198
199             dojo.forEach( this.fields, function (f) {
200                 var element = f.isControlfield() ? 'controlfield' : 'datafield';
201                 var f_node = doc.createElementNS( 'http://www.loc.gov/MARC21/slim', element );
202                 f_node.setAttribute('tag', f.tag);
203                 
204                 if (f.isControlfield()) {
205                     if (f.data) dojox.xml.parser.textContent(f_node, f.data);
206                 } else {
207                     f_node.setAttribute('ind1', f.indicator(1));
208                     f_node.setAttribute('ind2', f.indicator(2));
209                     dojo.forEach( f.subfields, function (sf) {
210                         var sf_node = doc.createElementNS('http://www.loc.gov/MARC21/slim', 'subfield');
211                         sf_node.setAttribute('code', sf[0]);
212                         dojox.xml.parser.textContent(sf_node, sf[1]);
213                         f_node.appendChild(sf_node);
214                     });
215                 }
216
217                 rec_node.appendChild(f_node);
218             });
219
220             return doc;
221         },
222
223         toXmlString : function () {
224             return dojox.xml.parser.innerXML( this.toXmlDocument() );
225         },
226
227         fromBreaker : function (marctxt) {
228             var me = this;
229
230             function cf_line_data (l) { return l.substring(4) || '' };
231             function df_line_data (l) { return l.substring(6) || '' };
232             function line_tag (l) { return l.substring(0,3) };
233             function df_ind1 (l) { return l.substring(4,5).replace('\\',' ') };
234             function df_ind2 (l) { return l.substring(5,6).replace('\\',' ') };
235             function isControlField (l) {
236                 var x = line_tag(l);
237                 return (x == 'LDR' || x < '010') ? true : false;
238             }
239             
240             var lines = marctxt.replace(/^=/gm,'').split('\n');
241             dojo.forEach(lines, function (current_line) {
242
243                 if (current_line.match(/^#/)) {
244                     // skip comment lines
245                 } else if (isControlField(current_line)) {
246                     if (line_tag(current_line) == 'LDR') {
247                         me.leader = cf_line_data(current_line) || '00000cam a2200205Ka 4500';
248                     } else {
249                         me.fields.push(
250                             new MARC.Field({
251                                 record : me,
252                                 tag    : line_tag(current_line),
253                                 data   : cf_line_data(current_line).replace('\\',' ','g')
254                             })
255                         );
256                     }
257                 } else {
258                     if (current_line.substring(4,5) == me.delimiter) // add delimiters if they were left out
259                         current_line = current_line.substring(0,3) + ' \\\\' + current_line.substring(4);
260
261                     var data = df_line_data(current_line);
262                     if (!(data.substring(0,1) == me.delimiter)) data = me.delimiter + 'a' + data;
263
264                     var sf_list = data.split(me.delimiter);
265                     sf_list.shift();
266
267                     me.fields.push(
268                         new MARC.Field({
269                                 record    : me,
270                                 tag       : line_tag(current_line),
271                                 ind1      : df_ind1(current_line),
272                                 ind2      : df_ind2(current_line),
273                                 subfields : dojo.map(
274                                     sf_list,
275                                     function (sf) {
276                                         var sf_data = sf.substring(1);
277                                         if (me.delimiter == '$') sf_data = sf_data.replace(/\{dollar\}/g, '$');
278                                          return [ sf.substring(0,1), sf_data ];
279                                     }
280                                 )
281                         })
282                     );
283                 }
284             });
285
286             return this;
287         },
288
289         toBreaker : function () {
290
291             var me = this;
292             var mtxt = '=LDR ' + this.leader + '\n';
293
294             mtxt += dojo.map( this.fields, function (f) {
295                 if (f.isControlfield()) {
296                     if (f.data) return '=' + f.tag + ' ' + f.data.replace(' ','\\','g');
297                     return '=' + f.tag;
298                 } else {
299                     return '=' + f.tag + ' ' +
300                         f.indicator(1).replace(' ','\\') + 
301                         f.indicator(2).replace(' ','\\') + 
302                         dojo.map( f.subfields, function (sf) {
303                             var sf_data = sf[1];
304                             if (me.delimiter == '$') sf_data = sf_data.replace(/\$/g, '{dollar}');
305                             return me.delimiter + sf[0] + sf_data;
306                         }).join('');
307                 }
308             }).join('\n');
309
310             return mtxt;
311         }
312     });
313 }