001package com.hfg.citation;
002
003import java.net.MalformedURLException;
004import java.net.URL;
005
006import com.hfg.css.CSS;
007import com.hfg.exception.ProgrammingException;
008import com.hfg.html.HTMLTag;
009import com.hfg.html.Span;
010import com.hfg.util.StringBuilderPlus;
011import com.hfg.util.StringUtil;
012import com.hfg.util.collection.CollectionUtil;
013import com.hfg.xml.msofficexml.docx.wordprocessingml.WmlParagraph;
014import com.hfg.xml.msofficexml.docx.wordprocessingml.WmlXMLTag;
015
016//------------------------------------------------------------------------------
017/**
018 APA (American Psychological Association) citation style.
019 <br/>
020 Example:
021 <pre>
022 Taylor, J. A., &amp; Johnson, R. S. (1997). Sequence database searches via de novo peptide sequencing
023   by tandem mass spectrometry. Rapid Communications in Mass Spectrometry, 11(9), 1067-1075.
024   doi:10.1002/(sici)1097-0231(19970615)11:93.0.co;2-l
025 </pre>
026 <div>
027 @author J. Alex Taylor, hairyfatguy.com
028 </div>
029 */
030//------------------------------------------------------------------------------
031// com.hfg XML/HTML Coding Library
032//
033// This library is free software; you can redistribute it and/or
034// modify it under the terms of the GNU Lesser General Public
035// License as published by the Free Software Foundation; either
036// version 2.1 of the License, or (at your option) any later version.
037//
038// This library is distributed in the hope that it will be useful,
039// but WITHOUT ANY WARRANTY; without even the implied warranty of
040// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
041// Lesser General Public License for more details.
042//
043// You should have received a copy of the GNU Lesser General Public
044// License along with this library; if not, write to the Free Software
045// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
046//
047// J. Alex Taylor, President, Founder, CEO, COO, CFO, OOPS hairyfatguy.com
048// jataylor@hairyfatguy.com
049//------------------------------------------------------------------------------
050
051public class APA implements CitationFormat
052{
053
054   //##########################################################################
055   // PUBLIC METHODS
056   //##########################################################################
057
058   //---------------------------------------------------------------------------
059   @Override
060   public String generateAsString(Citation inCitation)
061   {
062      String formattedCitation;
063
064      switch (inCitation.getType())
065      {
066         case journal:
067            formattedCitation = generateJournalCitationAsString(inCitation);
068            break;
069         case software:
070            formattedCitation = generateSoftwareCitationAsString(inCitation);
071            break;
072         default:
073            throw new ProgrammingException("No support for " + inCitation.getType() + " citations yet!");
074      }
075
076      return formattedCitation;
077   }
078
079   //---------------------------------------------------------------------------
080   @Override
081   public HTMLTag generateAsHTML(Citation inCitation)
082   {
083      HTMLTag tag;
084
085      switch (inCitation.getType())
086      {
087         case journal:
088            tag = generateJournalCitationAsHTML(inCitation);
089            break;
090         case software:
091            tag = generateSoftwareCitationAsHTML(inCitation);
092            break;
093         default:
094            throw new ProgrammingException("No support for " + inCitation.getType() + " citations yet!");
095      }
096
097      return tag;
098   }
099
100   //---------------------------------------------------------------------------
101   @Override
102   public WmlParagraph generateAsDocx(Citation inCitation, WmlXMLTag inParentTag)
103   {
104      WmlParagraph p;
105
106      switch (inCitation.getType())
107      {
108         case journal:
109            p = generateJournalCitationAsDocx(inCitation, inParentTag);
110            break;
111         case software:
112            p = generateSoftwareCitationAsDocx(inCitation, inParentTag);
113            break;
114         default:
115            throw new ProgrammingException("No support for " + inCitation.getType() + " citations yet!");
116      }
117
118      return p;
119   }
120
121   //##########################################################################
122   // PRIVATE METHODS
123   //##########################################################################
124
125   //---------------------------------------------------------------------------
126   private String generateAuthorList(Citation inCitation)
127   {
128      StringBuilderPlus authorList = null;
129
130      if (CollectionUtil.hasValues(inCitation.getAuthors()))
131      {
132         authorList = new StringBuilderPlus().setDelimiter(", ");
133
134         if (2 == inCitation.getAuthors().size())
135         {
136            authorList.setDelimiter(", & ");
137         }
138
139         for (Author author : inCitation.getAuthors())
140         {
141            authorList.delimitedAppend(author.getLastName());
142            authorList.append(", ");
143            authorList.append(author.getFirstInitial() + ".");
144
145            Character middleInitial = author.getMiddleInitial();
146            if (middleInitial != null)
147            {
148               authorList.append(" " + middleInitial + ".");
149            }
150         }
151      }
152
153      return authorList != null ? authorList.toString() : null;
154   }
155
156   //---------------------------------------------------------------------------
157   private String generateJournalCitationAsString(Citation inCitation)
158   {
159      return StringUtil.stripHTMLTags(generateJournalCitationAsHTML(inCitation).toHTML());
160   }
161
162   //---------------------------------------------------------------------------
163   private HTMLTag generateJournalCitationAsHTML(Citation inCitation)
164   {
165      Span tag = new Span();
166
167      String authorList = generateAuthorList(inCitation);
168
169      if (StringUtil.isSet(authorList))
170      {
171         tag.addContent(authorList);
172      }
173
174      if (inCitation.getYear() != null)
175      {
176         tag.addContent(" (" + inCitation.getYear() + ").");
177      }
178
179      if (StringUtil.isSet(inCitation.getTitle()))
180      {
181         tag.addContent(" " + inCitation.getTitle() + ".");
182      }
183
184      if (inCitation.getJournal() != null)
185      {
186         String journalString = inCitation.getJournal().getAbbrev();
187         if (null == journalString)
188         {
189            journalString = inCitation.getJournal().getTitle();
190         }
191
192         tag.addContent(" ");
193         tag.addSpan(journalString).addStyle(CSS.ITALIC);
194         tag.addContent(", ");
195      }
196
197      if (StringUtil.isSet(inCitation.getVolume()))
198      {
199         tag.addContent(inCitation.getVolume());
200      }
201
202      if (StringUtil.isSet(inCitation.getIssue()))
203      {
204         tag.addContent("(" + inCitation.getIssue() + "),");
205      }
206
207      if (StringUtil.isSet(inCitation.getPages()))
208      {
209         tag.addContent(" " + inCitation.getPages() + ".");
210      }
211
212      if (StringUtil.isSet(inCitation.getDOI()))
213      {
214         tag.addContent(" ");
215         if (!inCitation.getDOI().startsWith("doi"))
216         {
217            tag.addContent("doi:");
218         }
219         tag.addContent(inCitation.getDOI());
220      }
221
222      if (StringUtil.isSet(inCitation.getURL()))
223      {
224         tag.addContent(" Retrieved from ");
225         tag.addLink(inCitation.getURL(), inCitation.getURL());
226         tag.addContent(".");
227      }
228
229      return tag;
230   }
231
232   //---------------------------------------------------------------------------
233   private WmlParagraph generateJournalCitationAsDocx(Citation inCitation, WmlXMLTag inParentTag)
234   {
235      WmlParagraph p = new WmlParagraph(inParentTag.getParentDoc());
236      inParentTag.addSubtag(p);
237
238      String authorList = generateAuthorList(inCitation);
239
240      if (StringUtil.isSet(authorList))
241      {
242         p.addTextRun(authorList);
243      }
244
245      if (inCitation.getYear() != null)
246      {
247         p.addTextRun(" (" + inCitation.getYear() + ").");
248      }
249
250      if (StringUtil.isSet(inCitation.getTitle()))
251      {
252         p.addTextRun(" " + inCitation.getTitle() + ".");
253      }
254
255      if (inCitation.getJournal() != null)
256      {
257         String journalString = inCitation.getJournal().getAbbrev();
258         if (null == journalString)
259         {
260            journalString = inCitation.getJournal().getTitle();
261         }
262
263         p.addTextRun(" ");
264         p.addTextRun(journalString).getProperties().setItalics();
265         p.addTextRun(", ");
266      }
267
268      if (StringUtil.isSet(inCitation.getVolume()))
269      {
270         p.addTextRun(inCitation.getVolume());
271      }
272
273      if (StringUtil.isSet(inCitation.getIssue()))
274      {
275         p.addTextRun("(" + inCitation.getIssue() + "),");
276      }
277
278      if (StringUtil.isSet(inCitation.getPages()))
279      {
280         p.addTextRun(" " + inCitation.getPages() + ".");
281      }
282
283      if (StringUtil.isSet(inCitation.getDOI()))
284      {
285         p.addTextRun(" ");
286         if (!inCitation.getDOI().startsWith("doi"))
287         {
288            p.addTextRun("doi:");
289         }
290
291         try
292         {
293            String doiURL = inCitation.getDOI();
294            if (! doiURL.startsWith("http"))
295            {
296               doiURL = "http://doi.org/" + doiURL;   
297            }
298            
299            p.addHyperlink(new URL(doiURL), inCitation.getDOI());
300         }
301         catch (MalformedURLException e)
302         {
303            throw new RuntimeException(e);
304         }
305      }
306
307      if (StringUtil.isSet(inCitation.getURL()))
308      {
309         p.addTextRun(" Retrieved from ");
310
311         try
312         {
313            p.addHyperlink(new URL(inCitation.getURL()), inCitation.getURL());
314         }
315         catch (MalformedURLException e)
316         {
317            throw new RuntimeException(e);
318         }
319
320         p.addTextRun(".");
321      }
322
323      return p;
324   }
325
326   //---------------------------------------------------------------------------
327   private String generateSoftwareCitationAsString(Citation inCitation)
328   {
329      return StringUtil.stripHTMLTags(generateSoftwareCitationAsHTML(inCitation).toHTML());
330   }
331
332   //---------------------------------------------------------------------------
333   private HTMLTag generateSoftwareCitationAsHTML(Citation inCitation)
334   {
335      Span tag = new Span();
336
337      String authorList = generateAuthorList(inCitation);
338
339      if (StringUtil.isSet(authorList))
340      {
341         tag.addContent(authorList);
342
343         if (inCitation.getYear() != null)
344         {
345            tag.addContent(" (" + inCitation.getYear() + ").");
346         }
347
348         if (StringUtil.isSet(inCitation.getTitle()))
349         {
350            tag.addContent(" " + inCitation.getTitle() + " [Computer software].");
351         }
352      }
353      else
354      {
355         if (StringUtil.isSet(inCitation.getTitle()))
356         {
357            tag.addContent(inCitation.getTitle() + " [Computer software].");
358         }
359
360         if (inCitation.getYear() != null)
361         {
362            tag.addContent(" (" + inCitation.getYear() + ").");
363         }
364      }
365
366      if (StringUtil.isSet(inCitation.getPlaceOfPublication()))
367      {
368         tag.addContent(" " + inCitation.getPlaceOfPublication());
369      }
370
371      if (StringUtil.isSet(inCitation.getPublisher()))
372      {
373         tag.addContent(" " + inCitation.getPublisher());
374      }
375
376      if (!tag.getContent().endsWith("."))
377      {
378         tag.addContent(".");
379      }
380
381      return tag;
382   }
383
384
385
386   //---------------------------------------------------------------------------
387   private WmlParagraph generateSoftwareCitationAsDocx(Citation inCitation, WmlXMLTag inParentTag)
388   {
389      WmlParagraph p = new WmlParagraph(inParentTag.getParentDoc());
390      inParentTag.addSubtag(p);
391
392      String authorList = generateAuthorList(inCitation);
393
394      if (StringUtil.isSet(authorList))
395      {
396         p.addTextRun(authorList);
397
398         if (inCitation.getYear() != null)
399         {
400            p.addTextRun(" (" + inCitation.getYear() + ").");
401         }
402
403         if (StringUtil.isSet(inCitation.getTitle()))
404         {
405            p.addTextRun(" " + inCitation.getTitle() + " [Computer software].");
406         }
407      }
408      else
409      {
410         if (StringUtil.isSet(inCitation.getTitle()))
411         {
412            p.addTextRun(inCitation.getTitle() + " [Computer software].");
413         }
414
415         if (inCitation.getYear() != null)
416         {
417            p.addTextRun(" (" + inCitation.getYear() + ").");
418         }
419      }
420
421      if (StringUtil.isSet(inCitation.getPlaceOfPublication()))
422      {
423         p.addTextRun(" " + inCitation.getPlaceOfPublication()
424                      + (inCitation.getPlaceOfPublication().endsWith(".") ? "" : "."));
425      }
426
427      if (StringUtil.isSet(inCitation.getPublisher()))
428      {
429         p.addTextRun(" " + inCitation.getPublisher()
430                      + (inCitation.getPublisher().endsWith(".") ? "" : "."));
431      }
432
433      return p;
434   }
435}