001 /*
002 *
003 * $Revision: 14335 $ $Date: 2008-11-06 07:40:09 +0100 (Do, 06 Nov 2008) $
004 *
005 * This file is part of *** M y C o R e ***
006 * See http://www.mycore.de/ for details.
007 *
008 * This program is free software; you can use it, redistribute it
009 * and / or modify it under the terms of the GNU General Public License
010 * (GPL) as published by the Free Software Foundation; either version 2
011 * of the License or (at your option) any later version.
012 *
013 * This program is distributed in the hope that it will be useful, but
014 * WITHOUT ANY WARRANTY; without even the implied warranty of
015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
016 * GNU General Public License for more details.
017 *
018 * You should have received a copy of the GNU General Public License
019 * along with this program, in a file called gpl.txt or license.txt.
020 * If not, write to the Free Software Foundation Inc.,
021 * 59 Temple Place - Suite 330, Boston, MA 02111-1307 USA
022 */
023
024 package org.mycore.datamodel.metadata;
025
026 import java.util.ArrayList;
027 import java.util.Iterator;
028
029 import org.apache.log4j.Logger;
030 import org.jdom.Element;
031
032 import com.ibm.icu.util.Calendar;
033 import com.ibm.icu.util.GregorianCalendar;
034
035 import org.mycore.common.MCRCalendar;
036 import org.mycore.common.MCRException;
037
038 /**
039 * This class implements all methods for handling with the MCRMetaHistoryDate
040 * part of a metadata object. It use the GPL licensed ICU library of IBM.
041 *
042 * @author Juergen Vogler
043 * @author Jens Kupferschmidt
044 * @author Thomas Junge
045 * @version $Revision: 14335 $ $Date: 2008-11-06 07:40:09 +0100 (Do, 06 Nov 2008) $
046 * @see <a href="http://www.icu-project.org/">http://www.icu-project.org/</a>
047 */
048 public class MCRMetaHistoryDate extends MCRMetaDefault {
049
050 /** Logger */
051 protected static Logger LOGGER = Logger.getLogger(MCRMetaHistoryDate.class.getName());
052
053 /** The maximal length of 'text' */
054 public static final int MCRHISTORYDATE_MAX_TEXT = 256;
055
056 // Data of this class
057 private ArrayList<MCRMetaHistoryDateText> texts;
058
059 private Calendar von;
060
061 private Calendar bis;
062
063 private int ivon;
064
065 private int ibis;
066
067 private String calendar;
068
069 /**
070 * This is the constructor. <br>
071 * The language element was set to configured default. The text element is
072 * set to an empty string. The calendar is set to 'Gregorian Calendar'. The
073 * von value is set to MIN_JULIAN_DAY_NUMBER, the bis value is set to
074 * MAX_JULIAN_DAY_NUMBER;
075 */
076 public MCRMetaHistoryDate() {
077 super();
078 texts = new ArrayList<MCRMetaHistoryDateText>();
079 calendar = MCRCalendar.CALENDARS_INPUT[0];
080 setDefaultVon();
081 setDefaultBis();
082 }
083
084 /**
085 * This is the constructor. <br>
086 * The language element was set. If the value of <em>default_lang</em> is
087 * null, empty or false <b>en </b> was set. The subtag element was set to
088 * the value of <em>set_subtag<em>. If the value of <em>set_subtag</em>
089 * is null or empty an exception was throwed. The type element was set to
090 * the value of <em>set_type<em>, if it is null, an empty string was set
091 * to the type element.<br />
092 * The text element is set to an empty string. The calendar is set to 'Gregorian Calendar'. The von value
093 * is set to MIN_JULIAN_DAY_NUMBER, the bis value is set to MAX_JULIAN_DAY_NUMBER;
094 *
095 * @param set_datapart the global part of the elements like 'metadata'
096 * or 'service'
097 * @param set_subtag the name of the subtag
098 * @param default_lang the default language
099 * @param set_type the optional type string
100 * @param set_inherted a value >= 0
101 * @exception MCRException if the parameter values are invalid
102 */
103 public MCRMetaHistoryDate(String set_datapart, String set_subtag, String default_lang, String set_type, int set_inherted) throws MCRException {
104 super(set_datapart, set_subtag, default_lang, set_type, set_inherted);
105 texts = new ArrayList<MCRMetaHistoryDateText>();
106 calendar = MCRCalendar.CALENDARS_INPUT[0];
107 setDefaultVon();
108 setDefaultBis();
109 }
110
111 /**
112 * This method set the text field for the default language. If data exists,
113 * it overwrites the value of text.
114 *
115 * @param set_text
116 * the text string for a date or range
117 */
118 public final void setText(String set_text) {
119 setText(set_text, lang);
120 }
121
122 /**
123 * This method set the text field for the given language. If data exists, it
124 * overwrites the value of text.
125 *
126 * @param set_text
127 * the text string for a date or range
128 * @param set_lang
129 * the language of the text in the ISO format
130 */
131 public final void setText(String set_text, String set_lang) {
132 if (set_text == null) {
133 LOGGER.warn("The text field of MCRMeataHistoryDate is empty.");
134 return;
135 }
136 if (set_text.length() <= MCRHISTORYDATE_MAX_TEXT) {
137 set_text = set_text.trim();
138 } else {
139 set_text = set_text.substring(0, MCRHISTORYDATE_MAX_TEXT);
140 }
141 if (set_lang == null || set_lang.length() == 0) {
142 addText(set_text, lang);
143 } else {
144 addText(set_text, set_lang);
145 }
146 }
147
148 /**
149 * This method add a MCRMetaHistoryDateTexts instance to the ArrayList of
150 * texts.
151 *
152 * @param set_text
153 * the text- String
154 * @param set_lang
155 * the lang- String
156 */
157
158 public final void addText(String set_text, String set_lang) {
159 if (set_text == null) {
160 LOGGER.warn("The text field of MCRMeataHistoryDate is empty.");
161 return;
162 }
163 if (set_lang == null || set_lang.length() == 0) {
164 LOGGER.warn("The lang field of MCRMeataHistoryDate is empty.");
165 return;
166 }
167 for (int i = 0; i < texts.size(); i++) {
168 if (texts.get(i).getLang().equals(set_lang)) {
169 texts.remove(i);
170 break;
171 }
172 }
173 texts.add(new MCRMetaHistoryDateText(set_text, set_lang));
174 }
175
176 /**
177 * This method return the MCRMetaHistoryDateTexts instance with the
178 * corresponding language.
179 *
180 * @param set_lang
181 * the language String in ISO format
182 * @return an instance of MCRMetaHistoryDateTexts or null
183 */
184 public final MCRMetaHistoryDateText getText(String set_lang) {
185 if (set_lang == null)
186 return null;
187 for (int i = 0; i < texts.size(); i++) {
188 if (texts.get(i).getLang().equals(set_lang)) {
189 return texts.get(i);
190 }
191 }
192 return null;
193 }
194
195 /**
196 * This method return the MCRMetaHistoryDateTexts instance of the indexed
197 * element of the ArrayList.
198 *
199 * @param index
200 * the index of ArryList texts
201 * @return an instance of MCRMetaHistoryDateTexts or null
202 */
203 public final MCRMetaHistoryDateText getText(int index) {
204 if ((index >= 0) && (index < texts.size())) {
205 return texts.get(index);
206 }
207 return null;
208 }
209
210 /**
211 * This method read the ArryList texts
212 *
213 * @return an ArrayList of MCRMetaHistoryDateTexts instances
214 */
215 public final ArrayList<MCRMetaHistoryDateText> getTexts() {
216 return this.texts;
217 }
218
219 /**
220 * This method read the size of texts
221 *
222 * @return the size of the ArrayList of language dependence texts
223 */
224 public final int TextSize() {
225 return texts.size();
226 }
227
228 /**
229 * The method set the calendar String value.
230 *
231 * @param calstr
232 * the calendar as String, one of CALENDARS.
233 */
234 public final void setCalendar(String calstr) {
235 if (calstr == null) {
236 calendar = MCRCalendar.TAG_GREGORIAN;
237 LOGGER.warn("The calendar field of MCRMeataHistoryDate is set to default " + MCRCalendar.TAG_GREGORIAN + ".");
238 return;
239 }
240 for (int i = 0; i < MCRCalendar.CALENDARS_INPUT.length; i++) {
241 if (MCRCalendar.CALENDARS_INPUT[i].equals(calstr)) {
242 calendar = calstr;
243 return;
244 }
245 }
246 calendar = MCRCalendar.TAG_GREGORIAN;
247 LOGGER.warn("The calendar field of MCRMeataHistoryDate is set to default " + MCRCalendar.TAG_GREGORIAN + ".");
248 }
249
250 /**
251 * The method set the calendar String value.
252 *
253 * @param cal
254 * the date of the calendar.
255 */
256 public final void setCalendar(Calendar cal) {
257 if (cal instanceof GregorianCalendar) {
258 calendar = MCRCalendar.TAG_GREGORIAN;
259 return;
260 }
261 calendar = MCRCalendar.TAG_GREGORIAN;
262 }
263
264 /**
265 * The method set the von values to the default.
266 */
267 public final void setDefaultVon() {
268 ivon = MCRCalendar.MIN_JULIAN_DAY_NUMBER;
269 von = (Calendar) new GregorianCalendar();
270 von.set(GregorianCalendar.JULIAN_DAY, MCRCalendar.MIN_JULIAN_DAY_NUMBER);
271 }
272
273 /**
274 * The method set the bis values to the default.
275 */
276 public final void setDefaultBis() {
277 ibis = MCRCalendar.MAX_JULIAN_DAY_NUMBER;
278 bis = (Calendar) new GregorianCalendar();
279 bis.set(GregorianCalendar.JULIAN_DAY, MCRCalendar.MAX_JULIAN_DAY_NUMBER);
280 }
281
282 /**
283 * This method set the von to the given date of a supported calendar.
284 *
285 * @param set_date
286 * the date of a ICU supported calendar.
287 */
288 public final void setVonDate(Calendar set_date) {
289 if (set_date == null) {
290 setDefaultVon();
291 LOGGER.warn("The calendar to set 'von' is null, default is set.");
292 return;
293 }
294 ivon = set_date.get(GregorianCalendar.JULIAN_DAY);
295 von = set_date;
296
297 }
298
299 /**
300 * This method set the von to the given date.
301 *
302 * @param set_date
303 * a date string
304 * @param calstr
305 * the calendar as String, one of CALENDARS.
306 */
307 public final void setVonDate(String set_date, String calstr) {
308 Calendar c = von;
309 try {
310 c = MCRCalendar.getGregorianHistoryDate(set_date, false, calstr);
311 } catch (Exception e) {
312 LOGGER.warn("The von date " + set_date + " for calendar " + calstr + " is false.");
313 c = null;
314 }
315 setVonDate(c);
316 }
317
318 /**
319 * This method set the bis to the given date of a supported calendar.
320 *
321 * @param set_date
322 * the date of a ICU supported calendar
323 */
324 public final void setBisDate(Calendar set_date) {
325 if (set_date == null) {
326 setDefaultBis();
327 LOGGER.warn("The calendar to set 'bis' is null, default is set.");
328 return;
329 }
330 ibis = set_date.get(GregorianCalendar.JULIAN_DAY);
331 bis = set_date;
332 }
333
334 /**
335 * This method set the bis to the given date.
336 *
337 * @param set_date
338 * a date string
339 * @param calstr
340 * the calendar as String, one of CALENDARS.
341 */
342 public final void setBisDate(String set_date, String calstr) {
343 Calendar c = bis;
344 try {
345 c = MCRCalendar.getGregorianHistoryDate(set_date, true, calstr);
346 } catch (Exception e) {
347 LOGGER.warn("The bis date " + set_date + " for calendar " + calstr + " is false.");
348 c = null;
349 }
350 setBisDate(c);
351 }
352
353 /**
354 * This method get the 'text' text element.
355 *
356 * @return the text String of the default language or an empty String
357 * @deprecated
358 */
359 public final String getText() {
360 if (texts.size() > 0) {
361 MCRMetaHistoryDateText h = getText(lang);
362 if (h != null)
363 return h.getText();
364 else
365 return "";
366 }
367 return "";
368 }
369
370 /**
371 * This method get the 'calendar' text element.
372 *
373 * @return the calendar string
374 */
375 public final String getCalendar() {
376 return calendar;
377 }
378
379 /**
380 * This method get the von element as ICU-Calendar.
381 *
382 * @return the date
383 */
384 public final Calendar getVon() {
385 return von;
386 }
387
388 /**
389 * This method return the von as string.
390 *
391 * @return the date
392 */
393 public final String getVonToGregorianString() {
394 return MCRCalendar.getDateToFormattedString(von);
395 }
396
397 /**
398 * This method get the ivon element as Julian Day integer.
399 *
400 * @return the date
401 */
402 public final int getIvon() {
403 return ivon;
404 }
405
406 /**
407 * This method get the bis element as ICU-Calendar.
408 *
409 * @return the date
410 */
411 public final Calendar getBis() {
412 return bis;
413 }
414
415 /**
416 * This method return the bis as string.
417 *
418 * @return the date
419 */
420 public final String getBisToGregorianString() {
421 return MCRCalendar.getDateToFormattedString(bis);
422 }
423
424 /**
425 * This method get the ibis element as Julian Day integer.
426 *
427 * @return the date
428 */
429 public final int getIbis() {
430 return ibis;
431 }
432
433 /**
434 * This method reads the XML input stream part from a DOM part for the
435 * metadata of the document.
436 *
437 * @param element
438 * a relevant JDOM element for the metadata
439 */
440 public void setFromDOM(org.jdom.Element element) {
441 super.setFromDOM(element);
442 texts.clear(); // clear
443
444 String langn = "";
445 String textn;
446 Iterator<org.jdom.Element> textchild = element.getChildren("text").iterator();
447 while (textchild.hasNext()) {
448 Element elmt = (Element) textchild.next();
449 textn = elmt.getText();
450 langn = elmt.getAttributeValue("lang", org.jdom.Namespace.XML_NAMESPACE);
451 if (langn != null) {
452 setText(textn, langn);
453 } else {
454 setText(textn);
455 }
456 }
457 setCalendar(element.getChildTextTrim("calendar"));
458 setVonDate(element.getChildTextTrim("von"), calendar);
459 setBisDate(element.getChildTextTrim("bis"), calendar);
460 }
461
462 /**
463 * This method creates a XML stream for all data in this class, defined by
464 * the MyCoRe XML MCRMetaHistoryDate definition for the given subtag.
465 *
466 * @exception MCRException
467 * if the content of this class is not valid
468 * @return a JDOM Element with the XML MCRMetaHistoryDate part
469 */
470 public org.jdom.Element createXML() throws MCRException {
471 if (!isValid()) {
472 debug();
473 throw new MCRException("The content of MCRMetaHistoryDate is not valid.");
474 }
475
476 org.jdom.Element elm = new org.jdom.Element(subtag);
477 elm.setAttribute("lang", lang, org.jdom.Namespace.XML_NAMESPACE);
478 elm.setAttribute("inherited", Integer.toString(inherited));
479 for (int i = 0; i < texts.size(); i++) {
480 org.jdom.Element elmt = new org.jdom.Element("text");
481 elmt.addContent((String) texts.get(i).getText());
482 elmt.setAttribute("lang", texts.get(i).getLang(), org.jdom.Namespace.XML_NAMESPACE);
483 elm.addContent(elmt);
484 }
485 if ((type != null) && ((type = type.trim()).length() != 0)) {
486 elm.setAttribute("type", type);
487 }
488 if ((calendar = calendar.trim()).length() != 0) {
489 elm.addContent(new org.jdom.Element("calendar").addContent(calendar));
490 }
491
492 if (von != null) {
493 elm.addContent(new org.jdom.Element("ivon").addContent(Integer.toString(ivon)));
494 elm.addContent(new org.jdom.Element("von").addContent(getVonToGregorianString()));
495 }
496
497 if (bis != null) {
498 elm.addContent(new org.jdom.Element("ibis").addContent(Integer.toString(ibis)));
499 elm.addContent(new org.jdom.Element("bis").addContent(getBisToGregorianString()));
500 }
501 return elm;
502 }
503
504 /**
505 * This method checks the validation of the content of this class. The
506 * method returns <em>false</em> if
507 * <ul>
508 * <li>the number of texts is 0 (empty texts are delete)
509 * <li>von is null or bis is null or calendar is null
510 * </ul>
511 * otherwise the method returns <em>true</em>.
512 *
513 * @return a boolean value
514 */
515 public boolean isValid() {
516 for (int i = 0; i < texts.size(); i++) {
517 MCRMetaHistoryDateText textitem = texts.get(i);
518 if (!textitem.isValid()) {
519 texts.remove(i);
520 i--;
521 }
522 }
523 if (texts.size() == 0)
524 return false;
525 if ((von == null) || (bis == null) || (calendar == null)) {
526 return false;
527 }
528 if (ibis < ivon) {
529 Calendar swp = (Calendar) von.clone();
530 setVonDate((Calendar) bis.clone());
531 setBisDate(swp);
532 }
533
534 return true;
535 }
536
537 /**
538 * This method make a clone of this class.
539 */
540 public Object clone() {
541 MCRMetaHistoryDate out = new MCRMetaHistoryDate(datapart, subtag, lang, type, inherited);
542 for (int i = 0; i < texts.size(); i++) {
543 MCRMetaHistoryDateText h = texts.get(i);
544 out.setText(h.getText(), h.getLang());
545 }
546 out.setVonDate(von);
547 out.setBisDate(bis);
548 out.setCalendar(calendar);
549 return out;
550 }
551
552 /**
553 * This method put debug data to the logger (for the debug mode).
554 */
555 public void debug() {
556 super.debugDefault();
557 for (int i = 0; i < texts.size(); i++) {
558 LOGGER.debug("Text / lang = " + texts.get(i).getText() + " / " + texts.get(i).getLang());
559 }
560 LOGGER.debug("Calendar = " + calendar);
561 if (calendar.equals(MCRCalendar.TAG_GREGORIAN)) {
562 LOGGER.debug("Von (String) = " + getVonToGregorianString());
563 }
564 LOGGER.debug("Von (JulianDay) = " + ivon);
565 if (calendar.equals(MCRCalendar.TAG_GREGORIAN)) {
566 LOGGER.debug("Bis (String) = " + getBisToGregorianString());
567 }
568 LOGGER.debug("Bis (JulianDay) = " + ibis);
569 LOGGER.debug("Stop");
570 LOGGER.debug("");
571 }
572
573 /**
574 * This class describes the structure of pair of language an text. The
575 * language notation is in the ISO format.
576 *
577 */
578 protected class MCRMetaHistoryDateText {
579 private String datetext;
580
581 private String lang;
582
583 public MCRMetaHistoryDateText() {
584 this.datetext = "";
585 this.lang = DEFAULT_LANGUAGE;
586 }
587
588 public MCRMetaHistoryDateText(String datetext, String lang) {
589 setText(datetext);
590 setLang(lang);
591 }
592
593 /**
594 * This method get the datetext element as field text (String) .
595 *
596 * @return the datetext
597 */
598
599 public String getText() {
600 return this.datetext;
601 }
602
603 /**
604 * This method set the datetext element as field text (String) .
605 *
606 * @param datetext
607 * the text String of a date value
608 */
609 public void setText(String datetext) {
610 if (datetext == null) {
611 this.datetext = "";
612 } else {
613 this.datetext = datetext;
614 }
615 }
616
617 /**
618 * This method get the lang element as language field (String) .
619 *
620 * @return the lang
621 */
622 public String getLang() {
623 return this.lang;
624 }
625
626 /**
627 * This method set the lang element as language field (String) .
628 *
629 * @param set_lang
630 * the language String of a date value
631 */
632 public void setLang(String set_lang) {
633 if (set_lang == null) {
634 this.lang = DEFAULT_LANGUAGE;
635 } else {
636 this.lang = set_lang;
637 }
638 }
639
640 /**
641 * This mehtod validate the content. If lang and text are not empty, it return true otherwise it return false.
642 *
643 * @return true if the content is valid.
644 */
645 public boolean isValid() {
646 if ((this.lang.length() == 0) || (this.datetext.length() == 0)) return false;
647 return true;
648 }
649
650 }
651 }