Moving editor sources back into trunk
[taxeditor.git] / taxeditor-editor / src / main / java / eu / etaxonomy / taxeditor / propertysheet / reference / ReferencePropertySource.java
1 /**
2 * Copyright (C) 2007 EDIT
3 * European Distributed Institute of Taxonomy
4 * http://www.e-taxonomy.eu
5 *
6 * The contents of this file are subject to the Mozilla Public License Version 1.1
7 * See LICENSE.TXT at the top of this package for the full license terms.
8 */
9
10 package eu.etaxonomy.taxeditor.propertysheet.reference;
11
12 import java.beans.PropertyChangeEvent;
13 import java.beans.PropertyChangeListener;
14 import java.beans.PropertyChangeSupport;
15 import java.lang.reflect.Constructor;
16 import java.lang.reflect.InvocationTargetException;
17 import java.lang.reflect.Method;
18 import java.util.ArrayList;
19 import java.util.HashMap;
20 import java.util.LinkedHashMap;
21 import java.util.List;
22 import java.util.Set;
23 import java.util.Vector;
24
25 import org.apache.log4j.Logger;
26 import org.eclipse.ui.views.properties.ComboBoxPropertyDescriptor;
27 import org.eclipse.ui.views.properties.IPropertyDescriptor;
28 import org.eclipse.ui.views.properties.IPropertySource;
29 import org.eclipse.ui.views.properties.PropertyDescriptor;
30 import org.eclipse.ui.views.properties.TextPropertyDescriptor;
31
32 import eu.etaxonomy.cdm.common.CdmUtils;
33 import eu.etaxonomy.cdm.model.agent.Team;
34 import eu.etaxonomy.cdm.model.agent.TeamOrPersonBase;
35 import eu.etaxonomy.cdm.model.common.CdmBase;
36 import eu.etaxonomy.cdm.model.common.TimePeriod;
37 import eu.etaxonomy.cdm.model.reference.Article;
38 import eu.etaxonomy.cdm.model.reference.BibtexReference;
39 import eu.etaxonomy.cdm.model.reference.Book;
40 import eu.etaxonomy.cdm.model.reference.BookSection;
41 import eu.etaxonomy.cdm.model.reference.CdDvd;
42 import eu.etaxonomy.cdm.model.reference.Database;
43 import eu.etaxonomy.cdm.model.reference.Generic;
44 import eu.etaxonomy.cdm.model.reference.InProceedings;
45 import eu.etaxonomy.cdm.model.reference.Journal;
46 import eu.etaxonomy.cdm.model.reference.Map;
47 import eu.etaxonomy.cdm.model.reference.Patent;
48 import eu.etaxonomy.cdm.model.reference.PersonalCommunication;
49 import eu.etaxonomy.cdm.model.reference.PrintSeries;
50 import eu.etaxonomy.cdm.model.reference.PrintedUnitBase;
51 import eu.etaxonomy.cdm.model.reference.Proceedings;
52 import eu.etaxonomy.cdm.model.reference.PublicationBase;
53 import eu.etaxonomy.cdm.model.reference.ReferenceBase;
54 import eu.etaxonomy.cdm.model.reference.Report;
55 import eu.etaxonomy.cdm.model.reference.SectionBase;
56 import eu.etaxonomy.cdm.model.reference.StrictReferenceBase;
57 import eu.etaxonomy.cdm.model.reference.Thesis;
58 import eu.etaxonomy.cdm.model.reference.WebPage;
59 import eu.etaxonomy.taxeditor.propertysheet.TimePeriodPropertySource;
60 import eu.etaxonomy.taxeditor.propertysheet.YearValidator;
61 import eu.etaxonomy.taxeditor.store.model.Resources;
62 import eu.etaxonomy.taxeditor.store.model.TimeUtil;
63
64 /**
65 * Supplies the properties of a <code>ReferenceBase</code> object for display by
66 * a <code>PropertySheet</code>.
67 * <p>
68 * Includes a drop-down menu that allows the user to change <code>ReferenceBase</code>
69 * subclasses. This causes all fields except <code>TitleCache</code> to be wiped clean.
70 * <p>
71 * Normally, this would be called from another <code>IPropertySource</code>
72 * as follows:
73 * <pre>
74 * public Object getPropertyValue(Object id) {
75 *
76 * ...
77 *
78 * if (id.equals(P_ID_BIBREF)) {
79 * ReferenceBase citation = descriptionElement.getCitation();
80 * ReferencePropertySource bibRefPropertySource = new ReferencePropertySource(citation);
81 * bibRefPropertySource.addPropertyChangeListener(new PropertyChangeListener() {
82 * @Override
83 * public void propertyChange(PropertyChangeEvent evt) {
84 * descriptionElement.setCitation((ReferenceBase) evt.getNewValue());
85 * }
86 * });
87 * return bibRefPropertySource;
88 * }
89 * </pre>
90 * <p>
91 * Note: if <code>P_ID_BIBREF</code> in the above example is associated with an editable
92 * <code>TextPropertyDescriptor</code>, it will initalize its cell editor by calling
93 * <code>getEditableValue()</code>. If associated with a non-editable <code>PropertyDescriptor</code>,
94 * it will get its value from <code>getString()</code>.
95 * @author p.ciardelli
96 * @created 03.11.2008
97 * @version 1.0
98 */
99 public class ReferencePropertySource implements IPropertySource {
100 private static final Logger logger = Logger
101 .getLogger(ReferencePropertySource.class);
102
103 ReferenceBase reference;
104
105 // Property unique keys
106 public static final String P_ID_SEARCH = "P_ID_SEARCH";
107 public static final String P_ID_EDITABLECACHE = "P_ID_EDITABLECACHE";
108 public static final String P_ID_REFERENCETYPE = "P_ID_REFERENCETYPE";
109 public static final String P_ID_AUTHORTEAM = "P_ID_AUTHORTEAM";
110 public static final String P_ID_YEAR = "P_ID_YEAR";
111 public static final String P_ID_URI = "P_ID_URI";
112 public static final String P_ID_DATEPUBLISHED = "P_ID_DATEPUBLISHED";
113 public static final String P_ID_TITLE = "P_ID_TITLE";
114 public static final String P_ID_INJOURNAL = "P_ID_INJOURNAL";
115 public static final String P_ID_PAGES = "P_ID_PAGES";
116 public static final String P_ID_SERIES = "P_ID_SERIES";
117 public static final String P_ID_VOLUME = "P_ID_VOLUME";
118 public static final String P_ID_EDITOR = "P_ID_EDITOR";
119 public static final String P_ID_PLACEPUBLISHED = "P_ID_PLACEPUBLISHED";
120 public static final String P_ID_PUBLISHER = "P_ID_PUBLISHER";
121 public static final String P_ID_ISSN = "P_ID_ISSN";
122 public static final String P_ID_INSTITUTION = "P_ID_INSTITUTION";
123 public static final String P_ID_SCHOOL = "P_ID_SCHOOL";
124 public static final String P_ID_INSERIES = "P_ID_INSERIES";
125 public static final String P_ID_SERIESPART = "P_ID_SERIESPART";
126 public static final String P_ID_ISBN = "P_ID_ISBN";
127 public static final String P_ID_ORGANIZATION = "P_ID_ORGANIZATION";
128 public static final String P_ID_PRINTEDUNIT = "P_ID_PRINTEDUNIT";
129 public static final String P_ID_INBOOK = "P_ID_INBOOK";
130 public static final String P_ID_INPROCEEDINGS = "P_ID_INPROCEEDINGS";
131 public static final String P_ID_BIBTEX_ENTRYTYPE = "P_ID_BIBTEX_ENTRYTYPE";
132 public static final String P_ID_JOURNAL = "P_ID_JOURNAL";
133 public static final String P_ID_BOOKTITLE = "P_ID_BOOKTITLE";
134 public static final String P_ID_CHAPTER = "P_ID_CHAPTER";
135 public static final String P_ID_EDITION = "P_ID_EDITION";
136 public static final String P_ID_NUMBER = "P_ID_NUMBER";
137 public static final String P_ID_ANNOTE = "P_ID_ANNOTE";
138 public static final String P_ID_ADDRESS = "P_ID_ADDRESS";
139 public static final String P_ID_HOWPUBLISHED = "P_ID_HOWPUBLISHED";
140 public static final String P_ID_REPORTTYPE = "P_ID_REPORTTYPE";
141 public static final String P_ID_MONTH = "P_ID_MONTH";
142 public static final String P_ID_EPRINT = "P_ID_EPRINT";
143 public static final String P_ID_NOTE = "P_ID_NOTE";
144 public static final String P_ID_CROSSREF = "P_ID_CROSSREF";
145 public static final String P_ID_PROTECT_CACHE = "P_ID_PROTECT_CACHE";
146
147 // Property display keys
148 public static final String P_SEARCH = "Search";
149 public static final String P_EDITABLECACHE = "Editable Cache";
150 public static final String P_PROTECT_CACHE = "Protect Cache from overwriting?";
151 public static final String P_REFERENCETYPE = "Reference Type";
152 public static final String P_AUTHORTEAM = "Author Team (Cache)";
153 public static final String P_YEAR = "Year";
154 public static final String P_DATEPUBLISHED = "Date Published";
155 public static final String P_TITLE = "Title";
156 public static final String P_INJOURNAL = "In Journal";
157 public static final String P_VOLUME = "Volume";
158 public static final String P_EDITION = "Edition";
159 public static final String P_SERIES = "Series";
160 public static final String P_PAGES = "Pages";
161 public static final String P_EDITOR = "Editor";
162 public static final String P_PUBLISHER = "Publisher";
163 public static final String P_PLACEPUBLISHED = "Place Published";
164 public static final String P_ISSN = "ISSN";
165 public static final String P_INSTITUTION = "Institution";
166 public static final String P_SCHOOL = "School";
167 public static final String P_INSERIES = "In Series";
168 public static final String P_SERIESPART = "Series Part";
169 public static final String P_ISBN = "ISBN";
170 public static final String P_URI = "URI";
171 public static final String P_ORGANIZATION = "Organization";
172 public static final String P_PRINTEDUNIT = "Printed Unit";
173 public static final String P_INBOOK = "In Book";
174 public static final String P_INPROCEEDINGS = "In Proceedings";
175 public static final String P_BIBTEX_ENTRYTYPE = "BibTeX Entry Type";
176 public static final String P_JOURNAL = "Journal";
177 public static final String P_BOOKTITLE = "Book Title";
178 public static final String P_CHAPTER = "Chapter";
179 public static final String P_NUMBER = "Number";
180 public static final String P_ANNOTE = "Annote";
181 public static final String P_ADDRESS = "Address";
182 public static final String P_HOWPUBLISHED = "How Published";
183 public static final String P_REPORTTYPE = "Report Type";
184 public static final String P_MONTH = "Month";
185 public static final String P_EPRINT = "E-Print";
186 public static final String P_NOTE = "Note";
187 public static final String P_CROSSREF = "BibTeX Crossref";
188
189 protected static HashMap<Class, String> referenceTypeMap = null;
190
191 private static final String[] P_BIBTEX_ENTRYTYPE_MENU = new String[] {"ARTICLE", "BOOK", "BOOKLET", "INBOOK", "INCOLLECTION", "PROCEEDINGS", "INPROCEEDINGS", "CONFERENCE", "MANUAL", "MASTERTHESIS", "PHDTHESIS", "TECHREPORT", "UNPUBLISHED", "MISC"};
192
193 private static final int CACHE_NOT_PROTECTED = 0;
194 private static final int CACHE_PROTECTED = 1;
195
196 protected void populateReferenceTypes() {
197
198 // LinkedHashMap maintains insertion order
199 referenceTypeMap = new LinkedHashMap<Class, String>();
200
201 referenceTypeMap.put(ReferenceBase.class, "");
202 // referenceTypeMap.put(BibtexReference.class, "BibTeX Reference");
203 referenceTypeMap.put(Article.class, "Article");
204 referenceTypeMap.put(Generic.class, "Generic");
205 referenceTypeMap.put(Patent.class, "Patent");
206 referenceTypeMap.put(PersonalCommunication.class, "Personal Communication");
207 referenceTypeMap.put(CdDvd.class, "CD / DVD");
208 referenceTypeMap.put(Database.class, "Database");
209 referenceTypeMap.put(Journal.class, "Journal");
210 referenceTypeMap.put(Map.class, "Map");
211 referenceTypeMap.put(Book.class, "Book");
212 referenceTypeMap.put(Proceedings.class, "Proceedings");
213 referenceTypeMap.put(PrintSeries.class, "Print Series");
214 referenceTypeMap.put(Report.class, "Report");
215 referenceTypeMap.put(Thesis.class, "Thesis");
216 referenceTypeMap.put(WebPage.class, "Web Page");
217 referenceTypeMap.put(BookSection.class, "Book Section");
218 referenceTypeMap.put(InProceedings.class, "In Proceedings");
219 }
220
221 protected String[] getReferenceTypeArray() {
222 if (referenceTypeMap == null) {
223 populateReferenceTypes();
224 }
225 return referenceTypeMap.values().toArray(new String[] {});
226 }
227
228 protected Set<Class> getReferenceClassSet() {
229 return referenceTypeMap.keySet();
230 }
231
232 public ReferencePropertySource(ReferenceBase reference) {
233
234 // Default type of ReferenceBase is Generic
235 if (reference == null) {
236 reference = Generic.NewInstance();
237 }
238 // this.reference = CdmBase.deproxy(object, clazz)reference;
239 this.reference = reference;
240
241 initDescriptors();
242 }
243
244 protected void initDescriptors() {
245
246 List<String> displayFields = new ArrayList<String>();
247
248 // Drop-down menu to change reference type
249 displayFields.add(P_ID_REFERENCETYPE);
250
251 // ReferenceBase fields
252 displayFields.add(P_ID_SEARCH);
253 displayFields.add(P_ID_EDITABLECACHE);
254 displayFields.add(P_ID_PROTECT_CACHE);
255 displayFields.add(P_ID_AUTHORTEAM);
256 displayFields.add(P_ID_URI);
257
258 Class referenceClass = reference.getClass();
259
260 // if (reference instanceof BibtexReference) {
261 //
262 // displayFields.add(P_ID_BIBTEX_ENTRYTYPE);
263 // displayFields.add(P_ID_YEAR);
264 // displayFields.add(P_ID_JOURNAL);
265 // displayFields.add(P_ID_BOOKTITLE);
266 // displayFields.add(P_ID_CHAPTER);
267 // displayFields.add(P_ID_TITLE);
268 // displayFields.add(P_ID_SERIES);
269 // displayFields.add(P_ID_EDITION);
270 // displayFields.add(P_ID_VOLUME);
271 // displayFields.add(P_ID_NUMBER);
272 // displayFields.add(P_ID_PAGES);
273 // displayFields.add(P_ID_ANNOTE);
274 // displayFields.add(P_ID_EDITOR);
275 // displayFields.add(P_ID_INSTITUTION);
276 // displayFields.add(P_ID_SCHOOL);
277 // displayFields.add(P_ID_ORGANIZATION);
278 // displayFields.add(P_ID_PUBLISHER);
279 // displayFields.add(P_ID_ADDRESS);
280 // displayFields.add(P_ID_HOWPUBLISHED);
281 // displayFields.add(P_ID_REPORTTYPE);
282 // displayFields.add(P_ID_MONTH);
283 // displayFields.add(P_ID_EPRINT);
284 // displayFields.add(P_ID_NOTE);
285 // displayFields.add(P_ID_CROSSREF);
286 // }
287
288 if (reference instanceof StrictReferenceBase) {
289
290 displayFields.add(P_ID_DATEPUBLISHED);
291 displayFields.add(P_ID_TITLE);
292
293 if (referenceClass == Article.class) {
294 displayFields.add(P_ID_INJOURNAL);
295 displayFields.add(P_ID_PAGES);
296 displayFields.add(P_ID_SERIES);
297 displayFields.add(P_ID_VOLUME);
298 }
299
300 if (referenceClass == Generic.class) {
301 displayFields.add(P_ID_PAGES);
302 displayFields.add(P_ID_SERIES);
303 displayFields.add(P_ID_VOLUME);
304 displayFields.add(P_ID_EDITOR);
305 // displayFields.add(P_ID_PLACEPUBLISHED);
306 // displayFields.add(P_ID_PUBLISHER);
307 }
308
309 if (referenceClass == Patent.class) {
310 // No additional fields
311 }
312
313 if (referenceClass == PersonalCommunication.class) {
314 // No additional fields
315 }
316 if (reference instanceof PublicationBase) {
317
318 displayFields.add(P_ID_PLACEPUBLISHED);
319 displayFields.add(P_ID_PUBLISHER);
320
321 if (referenceClass == CdDvd.class) {
322 // No additional fields
323 }
324
325 if (referenceClass == Database.class) {
326 // No additional fields
327 }
328
329 if (referenceClass == Journal.class) {
330 displayFields.add(P_ID_ISSN);
331 }
332
333 if (referenceClass == Map.class) {
334 // No additional fields
335 }
336
337 if (referenceClass == PrintSeries.class) {
338 displayFields.add(P_ID_SERIES);
339 }
340
341 if (referenceClass == Report.class) {
342 displayFields.add(P_ID_INSTITUTION);
343 }
344
345 if (referenceClass == Thesis.class) {
346 displayFields.add(P_ID_SCHOOL);
347 }
348
349 if (referenceClass == WebPage.class) {
350 // No additional fields
351 }
352
353 if (reference instanceof PrintedUnitBase) {
354
355 displayFields.add(P_ID_EDITOR);
356 displayFields.add(P_ID_INSERIES);
357 displayFields.add(P_ID_PAGES);
358 displayFields.add(P_ID_SERIESPART);
359 displayFields.add(P_ID_VOLUME);
360
361 if (referenceClass == Book.class) {
362 displayFields.add(P_ID_ISBN);
363 displayFields.add(P_ID_EDITION);
364 }
365
366 if (referenceClass == Proceedings.class) {
367 displayFields.add(P_ID_ORGANIZATION);
368 }
369 }
370 }
371
372 if (reference instanceof SectionBase) {
373
374 displayFields.add(P_ID_PAGES);
375 displayFields.add(P_ID_PRINTEDUNIT);
376
377 if (referenceClass == BookSection.class) {
378 displayFields.add(P_ID_INBOOK);
379 }
380
381 if (referenceClass == InProceedings.class) {
382 displayFields.add(P_ID_INPROCEEDINGS);
383 }
384 }
385 }
386
387 // There was a problem with duplicate descriptors in the above code
388 List<String> displayFieldsTemp = new ArrayList<String>();
389 for (String field : displayFields) {
390 if (displayFieldsTemp.contains(field)) {
391 continue;
392 }
393 addDescriptor(field);
394 displayFieldsTemp.add(field);
395 }
396 }
397
398 protected Vector<PropertyDescriptor> descriptors = new Vector<PropertyDescriptor>();
399
400 protected void addDescriptor(String id) {
401
402 // Reference search
403 if (id.equals(P_ID_SEARCH)) {
404 descriptors.addElement(
405 new ReferenceSearchDescriptor(P_ID_SEARCH, P_SEARCH, getSearchType()) {
406 protected void saveReference(ReferenceBase reference) {
407 setPropertyValue(P_ID_SEARCH, reference);
408 }
409 });
410 }
411
412 // Editable cache
413 if (id.equals(P_ID_EDITABLECACHE)) {
414 descriptors.addElement(
415 new TextPropertyDescriptor(P_ID_EDITABLECACHE, P_EDITABLECACHE));
416 }
417
418 // Protect cache?
419 if (id.equals(P_ID_PROTECT_CACHE)) {
420 descriptors.addElement(
421 new ComboBoxPropertyDescriptor(P_ID_PROTECT_CACHE, P_PROTECT_CACHE,
422 new String[] {"no", "yes"}));
423 // descriptors.addElement(
424 // new CheckboxPropertyDescriptor(P_ID_PROTECT_CACHE, P_PROTECT_CACHE));
425 }
426
427 // Reference type
428 if (id.equals(P_ID_REFERENCETYPE)) {
429 descriptors.addElement(createReferenceTypeDescriptor());
430 }
431
432 boolean isProtectedCache = reference.isProtectedTitleCache();
433
434 // Author team
435 if (id.equals(P_ID_AUTHORTEAM)) {
436 descriptors.addElement(
437 isProtectedCache?
438 new PropertyDescriptor(P_ID_AUTHORTEAM, P_AUTHORTEAM) :
439 new TextPropertyDescriptor(P_ID_AUTHORTEAM, P_AUTHORTEAM));
440 }
441
442 // Year
443 if (id.equals(P_ID_YEAR)) {
444 descriptors.addElement(
445 isProtectedCache?
446 new PropertyDescriptor(P_ID_YEAR, P_YEAR) :
447 new TextPropertyDescriptor(P_ID_YEAR, P_YEAR));
448 }
449
450 // Date published
451 if (id.equals(P_ID_DATEPUBLISHED)) {
452
453 // TimePeriodPropertySource returns TimePeriod.getYear() - make this editable
454 if (isProtectedCache) {
455 descriptors.addElement(new PropertyDescriptor(
456 P_ID_DATEPUBLISHED, P_DATEPUBLISHED));
457 } else {
458 TextPropertyDescriptor yearDescriptor = new TextPropertyDescriptor(
459 P_ID_DATEPUBLISHED, P_DATEPUBLISHED);
460 yearDescriptor.setValidator(new YearValidator());
461 descriptors.addElement(yearDescriptor);
462 }
463 }
464
465 // URI
466 if (id.equals(P_ID_URI)) {
467 descriptors.addElement(
468 isProtectedCache?
469 new PropertyDescriptor(P_ID_URI, P_URI) :
470 new TextPropertyDescriptor(P_ID_URI, P_URI));
471 }
472
473 // Title
474 if (id.equals(P_ID_TITLE)) {
475 descriptors.addElement(
476 isProtectedCache?
477 new PropertyDescriptor(P_ID_TITLE, P_TITLE) :
478 new TextPropertyDescriptor(P_ID_TITLE, P_TITLE));
479 }
480
481 // In journal
482 if (id.equals(P_ID_INJOURNAL)) {
483 descriptors.addElement(
484 isProtectedCache?
485 new PropertyDescriptor(P_ID_INJOURNAL, P_INJOURNAL) :
486 new TextPropertyDescriptor(P_ID_INJOURNAL, P_INJOURNAL));
487 }
488
489 // Pages
490 if (id.equals(P_ID_PAGES)) {
491 descriptors.addElement(
492 isProtectedCache?
493 new PropertyDescriptor(P_ID_PAGES, P_PAGES) :
494 new TextPropertyDescriptor(P_ID_PAGES, P_PAGES));
495 }
496
497 // Series
498 if (id.equals(P_ID_SERIES)) {
499 descriptors.addElement(
500 isProtectedCache?
501 new PropertyDescriptor(P_ID_SERIES, P_SERIES) :
502 new TextPropertyDescriptor(P_ID_SERIES, P_SERIES));
503 }
504
505 // Volume
506 if (id.equals(P_ID_VOLUME )) {
507 descriptors.addElement(
508 isProtectedCache?
509 new PropertyDescriptor(P_ID_VOLUME, P_VOLUME) :
510 new TextPropertyDescriptor(P_ID_VOLUME, P_VOLUME));
511 }
512
513 // Editor
514 if (id.equals(P_ID_EDITOR)) {
515 descriptors.addElement(
516 isProtectedCache?
517 new PropertyDescriptor(P_ID_EDITOR, P_EDITOR) :
518 new TextPropertyDescriptor(P_ID_EDITOR, P_EDITOR));
519 }
520
521 // Edition
522 if (id.equals(P_ID_EDITION)) {
523 descriptors.addElement(
524 isProtectedCache?
525 new PropertyDescriptor(P_ID_EDITION, P_EDITION) :
526 new TextPropertyDescriptor(P_ID_EDITION, P_EDITION));
527 }
528
529 // Place published
530 if (id.equals(P_ID_PLACEPUBLISHED)) {
531 descriptors.addElement(
532 isProtectedCache?
533 new PropertyDescriptor(P_ID_PLACEPUBLISHED, P_PLACEPUBLISHED) :
534 new TextPropertyDescriptor(P_ID_PLACEPUBLISHED, P_PLACEPUBLISHED));
535 }
536
537 // Publisher
538 if (id.equals(P_ID_PUBLISHER)) {
539 descriptors.addElement(
540 isProtectedCache?
541 new PropertyDescriptor(P_ID_PUBLISHER, P_PUBLISHER) :
542 new TextPropertyDescriptor(P_ID_PUBLISHER, P_PUBLISHER));
543 }
544
545 // ISSN
546 if (id.equals(P_ID_ISSN)) {
547 descriptors.addElement(
548 isProtectedCache?
549 new PropertyDescriptor(P_ID_ISSN, P_ISSN) :
550 new TextPropertyDescriptor(P_ID_ISSN, P_ISSN));
551 }
552
553 // Institution
554 if (id.equals(P_ID_INSTITUTION)) {
555 descriptors.addElement(
556 isProtectedCache?
557 new PropertyDescriptor(P_ID_INSTITUTION, P_INSTITUTION) :
558 new TextPropertyDescriptor(P_ID_INSTITUTION, P_INSTITUTION));
559 }
560
561 // School
562 if (id.equals(P_ID_SCHOOL)) {
563 descriptors.addElement(
564 isProtectedCache?
565 new PropertyDescriptor(P_ID_SCHOOL, P_SCHOOL) :
566 new TextPropertyDescriptor(P_ID_SCHOOL, P_SCHOOL));
567 }
568
569 // In series
570 if (id.equals(P_ID_INSERIES)) {
571 descriptors.addElement(
572 isProtectedCache?
573 new PropertyDescriptor(P_ID_INSERIES, P_INSERIES) :
574 new TextPropertyDescriptor(P_ID_INSERIES, P_INSERIES));
575 }
576
577 // Series part
578 if (id.equals(P_ID_SERIESPART)) {
579 descriptors.addElement(
580 isProtectedCache?
581 new PropertyDescriptor(P_ID_SERIESPART, P_SERIESPART) :
582 new TextPropertyDescriptor(P_ID_SERIESPART, P_SERIESPART));
583 }
584
585 // ISBN
586 if (id.equals(P_ID_ISBN)) {
587 descriptors.addElement(
588 isProtectedCache?
589 new PropertyDescriptor(P_ID_ISBN, P_ISBN) :
590 new TextPropertyDescriptor(P_ID_ISBN, P_ISBN));
591 }
592
593 // Organization
594 if (id.equals(P_ID_ORGANIZATION)) {
595 descriptors.addElement(
596 isProtectedCache?
597 new PropertyDescriptor(P_ID_ORGANIZATION, P_ORGANIZATION) :
598 new TextPropertyDescriptor(P_ID_ORGANIZATION, P_ORGANIZATION));
599 }
600
601 // Printed unit
602 if (id.equals(P_ID_PRINTEDUNIT)) {
603 descriptors.addElement(
604 isProtectedCache?
605 new PropertyDescriptor(P_ID_PRINTEDUNIT, P_PRINTEDUNIT) :
606 new TextPropertyDescriptor(P_ID_PRINTEDUNIT, P_PRINTEDUNIT));
607 }
608
609 // In book
610 if (id.equals(P_ID_INBOOK)) {
611 descriptors.addElement(
612 isProtectedCache?
613 new PropertyDescriptor(P_ID_INBOOK, P_INBOOK) :
614 new TextPropertyDescriptor(P_ID_INBOOK, P_INBOOK));
615 }
616
617 // Bibtex entry type
618 if (id.equals(P_ID_BIBTEX_ENTRYTYPE)) {
619 descriptors.addElement(
620 isProtectedCache?
621 new PropertyDescriptor(P_ID_BIBTEX_ENTRYTYPE, P_BIBTEX_ENTRYTYPE) :
622 new ComboBoxPropertyDescriptor(P_ID_BIBTEX_ENTRYTYPE, P_BIBTEX_ENTRYTYPE, P_BIBTEX_ENTRYTYPE_MENU));
623 }
624 }
625
626 /**
627 * The default implementation of <code>ReferencePropertySource</code> will
628 * search all <code>ReferenceBase</code> classes.
629 *
630 * @return
631 */
632 protected int getSearchType() {
633 return IReferenceSearch.BIBREF;
634 }
635
636 /**
637 * The default implementation of <code>ReferencePropertySource</code> will show
638 * a drop-down of reference types, but subclasses may want to show a non-editable
639 * text descriptor of the reference type.
640 */
641 protected PropertyDescriptor createReferenceTypeDescriptor() {
642 return new ComboBoxPropertyDescriptor(
643 P_ID_REFERENCETYPE, P_REFERENCETYPE, getReferenceTypeArray());
644 }
645
646 /* (non-Javadoc)
647 * @see org.eclipse.ui.views.properties.IPropertySource#getEditableValue()
648 */
649 public Object getEditableValue() {
650 return CdmUtils.Nz(reference.getTitleCache());
651 }
652
653 /* (non-Javadoc)
654 * @see org.eclipse.ui.views.properties.IPropertySource#getPropertyDescriptors()
655 */
656 public IPropertyDescriptor[] getPropertyDescriptors() {
657 return (IPropertyDescriptor[]) descriptors.toArray(
658 new IPropertyDescriptor[descriptors.size()]);
659 }
660
661 /* (non-Javadoc)
662 * @see org.eclipse.ui.views.properties.IPropertySource#getPropertyValue(java.lang.Object)
663 */
664 public Object getPropertyValue(Object id) {
665
666 // Reference Type: get integer index of drop-down menu
667 if (id.equals(P_ID_REFERENCETYPE)) {
668 Class referenceClass = reference.getClass();
669 int menuIndex = 0;
670 // for (Class clazz : referenceTypeMap.keySet()) {
671 for (Class clazz : getReferenceClassSet()) {
672 if (clazz == referenceClass) {
673 return menuIndex;
674 }
675 menuIndex++;
676 }
677 logger.warn("Reference class type " + referenceClass + " not in reference type menu.");
678 return 0;
679 }
680
681 // Editable cache
682 if (id.equals(P_ID_EDITABLECACHE)) {
683 return (CdmUtils.Nz(reference.getTitleCache()));
684 }
685
686 // Protect cache?
687 if (id.equals(P_ID_PROTECT_CACHE)) {
688 if (reference.isProtectedTitleCache()) {
689 return CACHE_PROTECTED;
690 } else {
691 return CACHE_NOT_PROTECTED;
692 }
693 // return reference.isProtectedTitleCache();
694 }
695
696 // Author Team: for now, just edit the cache
697 // TODO AuthorTeamPropertySource
698 if (id.equals(P_ID_AUTHORTEAM)) {
699 TeamOrPersonBase authorTeam = reference.getAuthorTeam();
700
701 if (authorTeam == null) {
702 return "";
703 }
704
705 return CdmUtils.Nz(authorTeam.getTitleCache());
706 }
707
708 // Year
709 if (id.equals(P_ID_YEAR)) {
710 return CdmUtils.Nz(reference.getYear());
711 }
712
713 // URI
714 if (id.equals(P_ID_URI)) {
715 return CdmUtils.Nz(reference.getUri());
716 }
717
718 // Date published
719 if (id.equals(P_ID_DATEPUBLISHED)) {
720 TimePeriod datePublished = (TimePeriod) invokeMethod(reference, "getDatePublished", null);
721
722 if (datePublished == null) {
723 datePublished = TimePeriod.NewInstance();
724 }
725
726 if (reference.isProtectedTitleCache()) {
727 return CdmUtils.Nz(reference.getYear());
728 }
729
730 TimePeriodPropertySource timePeriodPropertySource =
731 new TimePeriodPropertySource(datePublished);
732 timePeriodPropertySource.addPropertyChangeListener(new PropertyChangeListener() {
733 public void propertyChange(PropertyChangeEvent evt) {
734 if (reference instanceof StrictReferenceBase && evt.getNewValue() instanceof TimePeriod) {
735 ((StrictReferenceBase) reference).setDatePublished((TimePeriod) evt.getNewValue());
736 }
737 }
738 });
739 return timePeriodPropertySource;
740 }
741
742 // Title: used by StrictReferenceBase
743 if (id.equals(P_ID_TITLE)) {
744 String title = (String) invokeMethod(reference, "getTitle", null);
745 return CdmUtils.Nz(title);
746 }
747
748 // InJournal: return an instance of ReferencePropertySource
749 if (id.equals(P_ID_INJOURNAL)) {
750
751 Journal inJournal = (Journal) invokeMethod(reference, "getInJournal", null);
752
753 if (inJournal == null) {
754 inJournal = Journal.NewInstance();
755 }
756
757 if (reference.isProtectedTitleCache()) {
758 return inJournal.getTitleCache();
759 }
760
761 ReferencePropertySource bibRefPropertySource = new SingleRefTypePropertySource(
762 inJournal, SingleRefTypePropertySource.JOURNAL);
763 bibRefPropertySource.addPropertyChangeListener(new PropertyChangeListener() {
764 public void propertyChange(PropertyChangeEvent evt) {
765 if (reference instanceof Article && evt.getNewValue() instanceof Journal) {
766 ((Article) reference).setInJournal((Journal) evt.getNewValue());
767 }
768 }
769 });
770 return bibRefPropertySource;
771 }
772
773 // Pages
774 if (id.equals(P_ID_PAGES)) {
775 String pages = (String) invokeMethod(reference, "getPages", null);
776 return CdmUtils.Nz(pages);
777 }
778
779 // Series
780 if (id.equals(P_ID_SERIES)) {
781 String series = (String) invokeMethod(reference, "getSeries", null);
782 return CdmUtils.Nz(series);
783 }
784
785 // Volume
786 if (id.equals(P_ID_VOLUME)) {
787 String volume = (String) invokeMethod(reference, "getVolume", null);
788 return CdmUtils.Nz(volume);
789 }
790
791 // Editor
792 if (id.equals(P_ID_EDITOR)) {
793 String editor = (String) invokeMethod(reference, "getEditor", null);
794 return CdmUtils.Nz(editor);
795 }
796
797 // Edition
798 if (id.equals(P_ID_EDITION)) {
799 String edition = (String) invokeMethod(reference, "getEdition", null);
800 return CdmUtils.Nz(edition);
801 }
802
803 // Place published
804 if (id.equals(P_ID_PLACEPUBLISHED)) {
805 String placePublished = (String) invokeMethod(reference, "getPlacePublished", null);
806 return CdmUtils.Nz(placePublished);
807 }
808
809 // Publisher
810 if (id.equals(P_ID_PUBLISHER)) {
811 String publisher = (String) invokeMethod(reference, "getPublisher", null);
812 return CdmUtils.Nz(publisher);
813 }
814
815 // ISSN
816 if (id.equals(P_ID_ISSN)) {
817 String issn = (String) invokeMethod(reference, "getIssn", null);
818 return CdmUtils.Nz(issn);
819 }
820
821 // Institution
822 if (id.equals(P_ID_INSTITUTION)) {
823 String institution = (String) invokeMethod(reference, "getInstitution", null);
824 return CdmUtils.Nz(institution);
825 }
826
827 // In series
828 if (id.equals(P_ID_INSERIES)) {
829
830 }
831
832 // ISBN
833 if (id.equals(P_ID_ISBN)) {
834 String isbn = (String) invokeMethod(reference, "getIsbn", null);
835 return CdmUtils.Nz(isbn);
836 }
837
838 // Organization
839 if (id.equals(P_ID_ORGANIZATION)) {
840 String organization = (String) invokeMethod(reference, "getOrganization", null);
841 return CdmUtils.Nz(organization);
842 }
843
844 // In book
845 if (id.equals(P_ID_INBOOK)) {
846
847 Book inBook = (Book) invokeMethod(reference, "getInBook", null);
848
849 if (inBook == null) {
850 inBook = Book.NewInstance();
851 }
852
853 ReferencePropertySource bibRefPropertySource = new SingleRefTypePropertySource(
854 inBook, SingleRefTypePropertySource.BOOK);
855 bibRefPropertySource.addPropertyChangeListener(new PropertyChangeListener() {
856 public void propertyChange(PropertyChangeEvent evt) {
857 if (reference instanceof BookSection && evt.getNewValue() instanceof Book) {
858 ((BookSection) reference).setInBook((Book) evt.getNewValue());
859 }
860 }
861 });
862 return bibRefPropertySource;
863 }
864
865 // Bibtex entry type
866 if (id.equals(P_ID_BIBTEX_ENTRYTYPE)) {
867
868 }
869
870 return "";
871 }
872
873 /**
874 * Executes <code>methodName</code> on <code>obj</code> with
875 * the argument <code>arg</code>.
876 * <p>
877 * On failure, returns <code>null</code>.
878 * <p>
879 * NOTE: both <code>Class.getMethod()</code> and <code>Method.invoke()</code>
880 * can be called with the <code>Object... args</code> approach, which allows
881 * the user to pass in a varying number of arguments. To keep it simple, and since
882 * this is usually only getters or setters, we are using only one argument.
883 * @param obj
884 * @param methodName
885 * @param args
886 * @return
887 */
888 private Object invokeMethod(Object obj, String methodName, Object arg) {
889 try {
890 Method method = null;
891 if (arg == null) {
892 method = obj.getClass().getMethod(methodName);
893 return method.invoke(obj);
894 } else {
895 method = obj.getClass().getMethod(methodName, arg.getClass());
896 return method.invoke(obj, arg);
897 }
898 } catch (SecurityException e) {
899 logger.error(e.getMessage());
900 } catch (IllegalArgumentException e) {
901 logger.error(e.getMessage());
902 } catch (NoSuchMethodException e) {
903 logger.error(e.getMessage());
904 } catch (IllegalAccessException e) {
905 logger.error(e.getMessage());
906 } catch (InvocationTargetException e) {
907 logger.error(e.getMessage());
908 }
909 return null;
910 }
911
912 /* (non-Javadoc)
913 * @see org.eclipse.ui.views.properties.IPropertySource#isPropertySet(java.lang.Object)
914 */
915 public boolean isPropertySet(Object id) {
916 return false;
917 }
918
919 /* (non-Javadoc)
920 * @see org.eclipse.ui.views.properties.IPropertySource#resetPropertyValue(java.lang.Object)
921 */
922 public void resetPropertyValue(Object id) {}
923
924 /* (non-Javadoc)
925 * @see org.eclipse.ui.views.properties.IPropertySource#setPropertyValue(java.lang.Object, java.lang.Object)
926 */
927 public void setPropertyValue(Object id, Object value) {
928
929 // Search result
930 if (id.equals(P_ID_SEARCH)) {
931 if (value instanceof ReferenceBase) {
932 reference = (ReferenceBase) value;
933 }
934 }
935
936 // Protect cache?
937 if (id.equals(P_ID_PROTECT_CACHE)) {
938 if (((Integer) value).intValue() == CACHE_PROTECTED) {
939 reference.setProtectedTitleCache(true);
940 } else {
941 reference.setProtectedTitleCache(false);
942 }
943 // reference.setProtectedTitleCache(((Boolean) value).booleanValue());
944 }
945
946 // Reference Type
947 if (id.equals(P_ID_REFERENCETYPE)) {
948
949 // NOTE: this code will only be reached if user actually changes choice in reference type
950 // dropdown list, not if focus is merely gained and lost without changing the value
951
952 // Grab reference's title cache
953 String oldTitleCache = reference.getTitleCache();
954
955 // Get reference's class
956 int menuIndex;
957 try {
958 menuIndex = ((Integer) value).intValue();
959 } catch (ClassCastException e) {
960 // Leave method / no change on class cast error
961 logger.error(e.getMessage());
962 return;
963 }
964 Class referenceClass = (Class)(getReferenceClassSet().toArray())[menuIndex];
965
966 // Make a new reference using the class
967 reference = makeNewReference(referenceClass);
968
969 // Set new reference's title cache
970 reference.setTitleCache(oldTitleCache);
971 }
972
973 // Author Team
974 if (id.equals(P_ID_AUTHORTEAM)) {
975 TeamOrPersonBase authorTeam = reference.getAuthorTeam();
976 if (authorTeam == null) {
977 authorTeam = Team.NewInstance();
978 reference.setAuthorTeam(authorTeam);
979 }
980 try {
981 authorTeam.setTitleCache((String) value);
982 } catch (ClassCastException e) {
983 // Leave method / no change on class cast error
984 logger.error(e.getMessage());
985 return;
986 }
987 }
988
989 // Citation
990 if (id.equals(P_ID_URI)) {
991 String uri = (String) value;
992 reference.setUri(uri);
993 }
994
995 // Year - only set directly by Bibtex refs
996 if (id.equals(P_ID_YEAR)) {
997 String year = (String) value;
998 if (reference instanceof BibtexReference) {
999 ((BibtexReference) reference).setYear(year);
1000 }
1001 }
1002
1003 // Title: used by StrictReferenceBase
1004 if (id.equals(P_ID_TITLE)) {
1005 String title = null;
1006 try {
1007 title = (String) value;
1008 } catch (ClassCastException e) {
1009 // Leave method / no change on class cast error
1010 logger.error(e.getMessage());
1011 return;
1012 }
1013 invokeMethod(reference, "setTitle", title);
1014 }
1015
1016 // Pages
1017 if (id.equals(P_ID_PAGES)) {
1018 invokeMethod(reference, "setPages", (String) value);
1019 }
1020
1021 // Series
1022 if (id.equals(P_ID_SERIES)) {
1023 invokeMethod(reference, "setSeries", (String) value);
1024 }
1025
1026 // Volume
1027 if (id.equals(P_ID_VOLUME)) {
1028 invokeMethod(reference, "setVolume", (String) value);
1029 }
1030
1031 // Editor
1032 if (id.equals(P_ID_EDITOR)) {
1033 invokeMethod(reference, "setEditor", (String) value);
1034 }
1035
1036 // Edition
1037 if (id.equals(P_ID_EDITION)) {
1038 invokeMethod(reference, "setEdition", (String) value);
1039 }
1040
1041 // Place published
1042 if (id.equals(P_ID_PLACEPUBLISHED)) {
1043 invokeMethod(reference, "setPlacePublished", (String) value);
1044 }
1045
1046 // Publisher
1047 if (id.equals(P_ID_PUBLISHER)) {
1048 invokeMethod(reference, "setPublisher", (String) value);
1049 }
1050
1051 // ISSN
1052 if (id.equals(P_ID_ISSN)) {
1053 invokeMethod(reference, "setIssn", (String) value);
1054 }
1055
1056 // Institution
1057 if (id.equals(P_ID_INSTITUTION)) {
1058 invokeMethod(reference, "setInstitution", (String) value);
1059 }
1060
1061 // ISBN
1062 if (id.equals(P_ID_ISBN)) {
1063 invokeMethod(reference, "setIsbn", (String) value);
1064 }
1065
1066 // Organization
1067 if (id.equals(P_ID_ORGANIZATION)) {
1068 invokeMethod(reference, "setOrganization", (String) value);
1069 }
1070
1071 // In book
1072 if (id.equals(P_ID_INBOOK)) {
1073 Book inBook = (Book) invokeMethod(reference, "getInBook", null);
1074 if (inBook == null) {
1075 inBook = Book.NewInstance();
1076 invokeMethod(reference, "setInBook", inBook);
1077 }
1078 inBook.setTitleCache((String) value);
1079 }
1080
1081 // Date published
1082 if (id.equals(P_ID_DATEPUBLISHED)) {
1083
1084 if (!(reference instanceof StrictReferenceBase)) {
1085 return;
1086 }
1087
1088 if (value instanceof String) {
1089 String year = (String) value;
1090 TimePeriod yearsPublished = null;
1091
1092 // If not empty, format is either "xxxx" or "xxxx-xxxx", thanks to validator
1093 if (!year.equals("")) {
1094
1095 // Convert to a TimePeriod
1096 yearsPublished = TimeUtil.convertTimePeriod(year);
1097
1098 // Update reference's dataPublished field
1099 TimePeriod datePublished = ((StrictReferenceBase) reference).getDatePublished();
1100
1101 if (datePublished == null) {
1102 ((StrictReferenceBase) reference).setDatePublished(yearsPublished);
1103 } else {
1104
1105 // Any months or days should be left as is - only update years
1106 datePublished.setStartYear(yearsPublished.getStartYear());
1107 datePublished.setEndYear(yearsPublished.getEndYear());
1108 }
1109 } else {
1110 ((StrictReferenceBase) reference).setDatePublished(null);
1111 }
1112
1113
1114 }
1115 }
1116
1117 // Editable cache
1118 if (id.equals(P_ID_EDITABLECACHE)) {
1119 reference.setTitleCache((String) value);
1120 } else {
1121 reference.setTitleCache(reference.generateTitle(), reference.isProtectedTitleCache());
1122 }
1123
1124 propertyChangeSupport.firePropertyChange(Resources.PROPERTY_SHEET_CHANGE, null, reference);
1125 }
1126
1127 /**
1128 * Takes a <code>referenceClass</code>, then executes either its <code>NewInstance()</code>
1129 * method or its constructor. Puts the resulting object in <code>this.reference</code> and
1130 * returns it.
1131 * <p>
1132 * If unsuccessful, <code>this.reference</code> keeps its old value and is returned.
1133 * @param referenceClass
1134 * @return
1135 */
1136 private ReferenceBase makeNewReference(Class referenceClass) {
1137
1138 // Check whether the class has a method "NewInstance()";
1139 try {
1140 Method method = referenceClass.getMethod("NewInstance", null);
1141 reference = (ReferenceBase) method.invoke(null, null);
1142 } catch (NoSuchMethodException e) {
1143 try {
1144 // If not, use its constructor
1145 Constructor constructor = referenceClass.getConstructor(null);
1146 reference = (ReferenceBase) constructor.newInstance(null);
1147 } catch (SecurityException e1) {
1148 e1.printStackTrace();
1149 } catch (NoSuchMethodException e1) {
1150 e1.printStackTrace();
1151 } catch (IllegalArgumentException e1) {
1152 e1.printStackTrace();
1153 } catch (InstantiationException e1) {
1154 e1.printStackTrace();
1155 } catch (IllegalAccessException e1) {
1156 e1.printStackTrace();
1157 } catch (InvocationTargetException e1) {
1158 e1.printStackTrace();
1159 }
1160 } catch (SecurityException e) {
1161 e.printStackTrace();
1162 } catch (IllegalArgumentException e) {
1163 e.printStackTrace();
1164 } catch (IllegalAccessException e) {
1165 e.printStackTrace();
1166 } catch (InvocationTargetException e) {
1167 e.printStackTrace();
1168 }
1169
1170 return reference;
1171 }
1172
1173 public String toString() {
1174 return CdmUtils.Nz(reference.getTitleCache());
1175 }
1176
1177 private PropertyChangeSupport propertyChangeSupport = new PropertyChangeSupport(this);
1178
1179 public void addPropertyChangeListener(
1180 PropertyChangeListener listener) {
1181 propertyChangeSupport.addPropertyChangeListener(listener);
1182 }
1183 }