View Javadoc

1   package yarfraw.utils.extension;
2   
3   import static yarfraw.io.parser.ExtensionElementQname.*;
4   import static yarfraw.utils.XMLUtils.same;
5   
6   import java.math.BigDecimal;
7   import java.math.BigInteger;
8   import java.util.ArrayList;
9   import java.util.Iterator;
10  import java.util.List;
11  
12  import javax.xml.bind.JAXBContext;
13  import javax.xml.bind.JAXBElement;
14  import javax.xml.bind.JAXBException;
15  import javax.xml.bind.Marshaller;
16  import javax.xml.bind.Unmarshaller;
17  import javax.xml.datatype.XMLGregorianCalendar;
18  import javax.xml.namespace.QName;
19  import javax.xml.parsers.DocumentBuilderFactory;
20  import javax.xml.parsers.ParserConfigurationException;
21  
22  import org.apache.commons.logging.Log;
23  import org.apache.commons.logging.LogFactory;
24  import org.georss.georss._10.GeoRssExtension;
25  import org.georss.georss._10.SimplePositionType;
26  import org.georss.georss._10.Where;
27  import org.w3c.dom.Document;
28  import org.w3c.dom.Element;
29  import org.w3c.dom.Node;
30  import org.w3c.dom.NodeList;
31  
32  import yarfraw.core.datamodel.FeedFormat;
33  import yarfraw.core.datamodel.YarfrawException;
34  import yarfraw.generated.admin.elements.AdminExtension;
35  import yarfraw.generated.admin.elements.AdminType;
36  import yarfraw.generated.atom03.ext.elements.Atom03Extension;
37  import yarfraw.generated.atom03.ext.elements.ContentType;
38  import yarfraw.generated.blogger.elements.BloggerExtension;
39  import yarfraw.generated.feedburner.elements.FeedburnerExtension;
40  import yarfraw.generated.googlebase.elements.CurrencyCodeEnumeration;
41  import yarfraw.generated.googlebase.elements.DateTimeRangeType;
42  import yarfraw.generated.googlebase.elements.GenderEnumeration;
43  import yarfraw.generated.googlebase.elements.GoogleBaseExtension;
44  import yarfraw.generated.googlebase.elements.ObjectFactory;
45  import yarfraw.generated.googlebase.elements.PaymentMethodEnumeration;
46  import yarfraw.generated.googlebase.elements.PriceTypeEnumeration;
47  import yarfraw.generated.googlebase.elements.ShippingType;
48  import yarfraw.generated.itunes.elements.ItunesCategoryType;
49  import yarfraw.generated.itunes.elements.ItunesExtension;
50  import yarfraw.generated.itunes.elements.ItunesImageType;
51  import yarfraw.generated.itunes.elements.ItunesOwnerType;
52  import yarfraw.generated.mrss.elements.MrssCategoryType;
53  import yarfraw.generated.mrss.elements.MrssContentType;
54  import yarfraw.generated.mrss.elements.MrssCopyrightType;
55  import yarfraw.generated.mrss.elements.MrssCreditType;
56  import yarfraw.generated.mrss.elements.MrssDescriptionType;
57  import yarfraw.generated.mrss.elements.MrssExtension;
58  import yarfraw.generated.mrss.elements.MrssGroupType;
59  import yarfraw.generated.mrss.elements.MrssHashType;
60  import yarfraw.generated.mrss.elements.MrssPlayerType;
61  import yarfraw.generated.mrss.elements.MrssRatingType;
62  import yarfraw.generated.mrss.elements.MrssRestrictionType;
63  import yarfraw.generated.mrss.elements.MrssTextType;
64  import yarfraw.generated.mrss.elements.MrssThumbnailType;
65  import yarfraw.generated.mrss.elements.MrssTitleType;
66  import yarfraw.generated.rss10.elements.DcType;
67  import yarfraw.generated.rss10.elements.DublinCoreExtension;
68  import yarfraw.generated.rss10.elements.SyndicationExtension;
69  import yarfraw.generated.rss10.elements.UpdatePeriodEnum;
70  import yarfraw.generated.slash.elements.SlashExtension;
71  import yarfraw.generated.wfw.elements.WellFormedWebExtension;
72  import yarfraw.utils.JAXBUtils;
73  
74  public class ExtensionUtils{
75    private static final String HTTP_BASE_GOOGLE_COM_CNS_1_0 = "http://base.google.com/ns/1.0";
76    private static final String ITUNES_JAXB_CONTEXT = "yarfraw.generated.itunes.elements";
77    private static final String MRSS_JAXB_CONTEXT = "yarfraw.generated.mrss.elements";
78    private static final String GOOGLEBASE_JAXB_CONTEXT = "yarfraw.generated.googlebase.elements";
79    private static final String DUBLINCORE_JAXB_CONTEXT = "yarfraw.generated.rss10.elements";
80    private static final String GEORSS_JAXB_CONTEXT = "org.georss.georss._10";
81    private static final String WFW_JAXB_CONTEXT = "yarfraw.generated.wfw.elements";
82    private static final String SY_JAXB_CONTEXT = "yarfraw.generated.rss10.elements";
83    private static final String BLOGGER_JAXB_CONTEXT = "yarfraw.generated.blogger.elements";
84    private static final String ADMIN_JAXB_CONTEXT = "yarfraw.generated.admin.elements";
85    private static final String FEEDBURNER_JAXB_CONTEXT = "yarfraw.generated.feedburner.elements";
86    private static final String SLASH_JAXB_CONTEXT = "yarfraw.generated.slash.elements";
87    private static final String ATOM03_JAXB_CONTEXT = "yarfraw.generated.atom03.ext.elements";
88  
89    
90    //FIXME: should merge the constants into the enum
91    private static enum ContextEnum{
92      DC, SY, ITUNES, GOOGLEBASE, WFW, MRSS, GEORSS, BLOGGER, ADMIN, FEEDBURNER, SLASH, ATOM03
93    }
94    
95    private static final ObjectFactory GOOGLEBASE_FACTORY = new ObjectFactory();
96    
97    private static final Log LOG = LogFactory.getLog(ExtensionUtils.class);
98    private ExtensionUtils(){}
99    
100   
101   /***
102    * Extracts the Atom 0.3 extension elements <b>that are not mapped to the core models</b>
103    * from the input list into an {@link Atom03Extension}
104    * object. <br/>
105    * The extracted elements will be removed from the original input list.
106    * <br/>
107    * see http://yarfraw.sourceforge.net about these
108    * extension elements
109    * @param otherElements - any elements
110    * @return an {@link Atom03Extension} object
111    * @throws YarfrawException 
112    */
113   @SuppressWarnings("unchecked")
114   public static Atom03Extension extractAtom03Extension(List<Element> otherElements) throws YarfrawException {
115     Atom03Extension ret = new Atom03Extension();
116     try{
117       if(otherElements != null){
118         Unmarshaller u = getContext(ContextEnum.ATOM03).createUnmarshaller();
119         Iterator<Element> it = otherElements.iterator();
120         while(it.hasNext()){
121           Element e = it.next();
122           if(e == null){
123             continue;
124           }
125           QName name = new QName(e.getNamespaceURI(), e.getLocalName());
126           if(same(name, ATOM03_CONTENT_QNAME)){
127             ContentType c = ((JAXBElement<ContentType>)u.unmarshal(e)).getValue();
128             ret.getContent().add(c);
129             it.remove();
130           }else if(same(name, ATOM03_INFO_QNAME)){
131             ContentType c = ((JAXBElement<ContentType>)u.unmarshal(e)).getValue();
132             ret.setInfo(c);
133             it.remove();
134           }else if(same(name, ATOM03_ISSUED_QNAME)){
135             ret.setIssued(e.getTextContent());
136             it.remove();
137           }else if(same(name, ATOM03_SUMMARY_QNAME)){
138             ContentType c = ((JAXBElement<ContentType>)u.unmarshal(e)).getValue();
139             ret.setSummary(c);
140             it.remove();
141           }else if(same(name, ATOM03_TITLE_QNAME)){
142             ContentType c = ((JAXBElement<ContentType>)u.unmarshal(e)).getValue();
143             ret.setTitle(c);
144             it.remove();
145           }else if(same(name, ATOM03_TAGLINE_QNAME)){
146             ContentType c = ((JAXBElement<ContentType>)u.unmarshal(e)).getValue();
147             ret.setTagline(c);
148             it.remove();
149           }
150         }
151       }
152     }catch (JAXBException e) {
153       throw new YarfrawException("unable to unmarshal element", e);
154     }
155     return ret;
156   }
157   
158   /***
159    * Extracts the itunes extension elements from the input list into an {@link ItunesExtension}
160    * object. <br/>
161    * The extracted elements will be removed from the original input list.
162    * <br/>
163    * see http://www.apple.com/itunes/store/podcaststechspecs.html about these
164    * extension elements
165    * @param otherElements - any elements
166    * @return an {@link ItunesExtension} object
167    * @throws YarfrawException 
168    */
169   @SuppressWarnings("unchecked")
170   public static ItunesExtension extractItunesExtension(List<Element> otherElements) throws YarfrawException {
171     ItunesExtension ret = new ItunesExtension();
172     try{
173       if(otherElements != null){
174         Unmarshaller u = getContext(ContextEnum.ITUNES).createUnmarshaller();
175         Iterator<Element> it = otherElements.iterator();
176         while(it.hasNext()){
177           Element e = it.next();
178           if(e == null){
179             continue;
180           }
181           QName name = new QName(e.getNamespaceURI(), e.getLocalName());
182           if(same(name, ITUNES_AUTHOR_QNAME)){
183             ret.setAuthor(e.getTextContent());
184             it.remove();
185           }else if(same(name, ITUNES_BLOCK_QNAME)){
186             ret.setBlock(e.getTextContent());
187             it.remove();
188           }else if(same(name, ITUNES_CATEGORY_QNAME)){
189             ItunesCategoryType cat = ((JAXBElement<ItunesCategoryType>)u.unmarshal(e)).getValue();
190             ret.getCategory().add(cat);
191             it.remove();
192           }else if(same(name, ITUNES_DURATION_QNAME)){
193             ret.setDuration(e.getTextContent());
194             it.remove();
195           }else if(same(name, ITUNES_EXPLICIT_QNAME)){
196             ret.setExplicit(e.getTextContent());
197             it.remove();
198           }else if(same(name, ITUNES_IMAGE_QNAME)){
199             ItunesImageType img  = ((JAXBElement<ItunesImageType>)u.unmarshal(e)).getValue();
200             ret.setImage(img);
201             it.remove();
202           }else if(same(name, ITUNES_KEYWORDS_QNAME)){
203             ret.setKeywords(e.getTextContent());
204             it.remove();
205           }else if(same(name, ITUNES_OWNER_QNAME)){
206             ItunesOwnerType owner = ((JAXBElement<ItunesOwnerType>)u.unmarshal(e)).getValue();
207             ret.setOwner(owner);
208             it.remove();
209           }else if(same(name, ITUNES_SUBTITLE_QNAME)){
210             ret.setSubtitle(e.getTextContent());
211             it.remove();
212           }else if(same(name, ITUNES_SUMMARY_QNAME)){
213             ret.setSummary(e.getTextContent());
214             it.remove();
215           }else if(same(name, ITUNES_NewFeedUrl_QNAME)){
216             ret.setNewFeedUrl(e.getTextContent());
217             it.remove();
218           }
219         }
220       }
221     }catch (JAXBException e) {
222       throw new YarfrawException("unable to unmarshal element", e);
223     }
224     return ret;
225   }
226 
227   /***
228    * Extracts the itunes extension elements from the input list into an {@link DublinCoreExtension}
229    * object. <br/>
230    * The extracted elements will be removed from the original input list.
231    * <br/>
232    * see http://dublincore.org/documents/2002/07/31/dcmes-xml/ about these
233    * extension elements
234    * @param otherElements - any elements
235    * @return an {@link DublinCoreExtension} object
236    * @throws YarfrawException 
237    */
238   @SuppressWarnings("unchecked")
239   public static DublinCoreExtension extractDublinCoreExtension(List<Element> otherElements) throws YarfrawException {
240     DublinCoreExtension ret = new DublinCoreExtension();
241     try {
242       if(otherElements != null){
243         Iterator<Element> it = otherElements.iterator();
244         Unmarshaller u = getContext(ContextEnum.SY).createUnmarshaller();
245         while(it.hasNext()){
246           Element e = it.next();
247           if(e == null){
248             continue;
249           }
250           QName name = new QName(e.getNamespaceURI(), e.getLocalName());
251           if(same(name, DC_Contributor_QNAME)){
252             ret.getContributor().add(((JAXBElement<DcType>)u.unmarshal(e)).getValue());
253             it.remove();
254           }else if(same(name, DC_Coverage_QNAME)){
255             ret.setCoverage(((JAXBElement<DcType>)u.unmarshal(e)).getValue());
256             it.remove();
257           }else if(same(name, DC_Creator_QNAME)){
258             ret.setCreator(((JAXBElement<DcType>)u.unmarshal(e)).getValue());
259             it.remove();
260           }else if(same(name, DC_Date_QNAME)){
261             ret.setDate(((JAXBElement<DcType>)u.unmarshal(e)).getValue());
262             it.remove();
263           }else if(same(name, DC_Description_QNAME)){
264             ret.setDescription(((JAXBElement<DcType>)u.unmarshal(e)).getValue());
265             it.remove();
266           }else if(same(name, DC_Format_QNAME)){
267             ret.setFormat(((JAXBElement<DcType>)u.unmarshal(e)).getValue());
268             it.remove();
269           }else if(same(name, DC_Identifier_QNAME)){
270             ret.setIdentifier(((JAXBElement<DcType>)u.unmarshal(e)).getValue());
271             it.remove();
272           }else if(same(name, DC_Language_QNAME)){
273             ret.setLanguage(((JAXBElement<DcType>)u.unmarshal(e)).getValue());
274             it.remove();
275           }else if(same(name, DC_Publisher_QNAME)){
276             ret.setPublisher(((JAXBElement<DcType>)u.unmarshal(e)).getValue());
277             it.remove();
278           }else if(same(name, DC_Relation_QNAME)){
279             ret.setRelation(((JAXBElement<DcType>)u.unmarshal(e)).getValue());
280             it.remove();
281           }else if(same(name, DC_Rights_QNAME)){
282             ret.setRights(((JAXBElement<DcType>)u.unmarshal(e)).getValue());
283             it.remove();
284           }else if(same(name, DC_Source_QNAME)){
285             ret.setSource(((JAXBElement<DcType>)u.unmarshal(e)).getValue());
286             it.remove();
287           }else if(same(name, DC_Subject_QNAME)){
288             ret.getSubject().add(((JAXBElement<DcType>)u.unmarshal(e)).getValue());
289             it.remove();
290           }else if(same(name, DC_Title_QNAME)){
291             ret.setTitle(((JAXBElement<DcType>)u.unmarshal(e)).getValue());
292             it.remove();
293           }else if(same(name, DC_Type_QNAME)){
294             ret.setType(((JAXBElement<DcType>)u.unmarshal(e)).getValue());
295             it.remove();
296           }
297         }
298       }
299     }catch (JAXBException e) {
300       throw new YarfrawException("unable to unmarshal element", e);
301     }
302     return ret;
303   }
304   
305   /***
306    * Extracts the well-formed web extension elements from the input list into an {@link WellFormedWebExtension}
307    * object. <br/>
308    * The extracted elements will be removed from the original input list.
309    * <br/>
310    * see http://wellformedweb.org/news/wfw_namespace_elements about these
311    * extension elements
312    * @param otherElements - any elements
313    * @return an {@link WellFormedWebExtension} object
314    * @throws YarfrawException 
315    */
316   public static WellFormedWebExtension extractWellFormedWebExtension(List<Element> otherElements) throws YarfrawException {
317     WellFormedWebExtension ret = new WellFormedWebExtension();
318       if(otherElements != null){
319         Iterator<Element> it = otherElements.iterator();
320         while(it.hasNext()){
321           Element e = it.next();
322           if(e == null){
323             continue;
324           }
325           QName name = new QName(e.getNamespaceURI(), e.getLocalName());
326           if(same(name, WFW_Comment_QNAME)){
327             ret.setComment(e.getTextContent());
328             it.remove();
329           }else if(same(name, WFW_CommentRss_QNAME)){
330             ret.setCommentRss(e.getTextContent());
331             it.remove();
332           }
333         }
334       }
335     return ret;
336   }
337 
338   /***
339    * Extracts the well-formed web extension elements from the input list into an {@link AdminExtension}
340    * object. <br/>
341    * The extracted elements will be removed from the original input list.
342    * <br/>
343    * see http://web.resource.org/rss/1.0/modules/admin/ about these
344    * extension elements
345    * @param otherElements - any elements
346    * @return an {@link AdminExtension} object
347    * @throws YarfrawException 
348    */
349   @SuppressWarnings("unchecked")
350   public static AdminExtension extractAdminExtension(List<Element> otherElements) throws YarfrawException {
351     AdminExtension ret = new AdminExtension();
352     try {
353       if(otherElements != null){
354         Iterator<Element> it = otherElements.iterator();
355         Unmarshaller u = getContext(ContextEnum.ADMIN).createUnmarshaller();
356         while(it.hasNext()){
357           Element e = it.next();
358           if(e == null){
359             continue;
360           }
361           QName name = new QName(e.getNamespaceURI(), e.getLocalName());
362           if(same(name, ADMIN_ErrorReportsTo_QNAME)){
363             if(e.getTextContent() != null){
364               ret.setErrorReportsTo(((JAXBElement<AdminType>)u.unmarshal(e)).getValue());
365             }
366           }else if(same(name, ADMIN_GeneratorAgent_QNAME)){
367             if(e.getTextContent() != null){
368               ret.setGeneratorAgent(((JAXBElement<AdminType>)u.unmarshal(e)).getValue());
369             }
370           }
371         }
372       }
373     }
374     catch (JAXBException e) {
375       throw new YarfrawException("unable to unmarshal element", e);
376     }
377 
378     return ret;
379   }
380   
381   /***
382    * Extracts the feedburner extension elements from the input list into an {@link FeedburnerExtension}
383    * object. <br/>
384    * The extracted elements will be removed from the original input list.
385    * <br/>
386    * see www.feedburner.com about these
387    * extension elements
388    * @param otherElements - any elements
389    * @return an {@link FeedburnerExtension} object
390    * @throws YarfrawException 
391    */
392   @SuppressWarnings("unchecked")
393   public static FeedburnerExtension extractFeedburnerExtension(List<Element> otherElements) throws YarfrawException {
394     FeedburnerExtension ret = new FeedburnerExtension();
395     if(otherElements != null){
396       Iterator<Element> it = otherElements.iterator();
397       while(it.hasNext()){
398         Element e = it.next();
399         if(e == null){
400           continue;
401         }
402         QName name = new QName(e.getNamespaceURI(), e.getLocalName());
403         if(same(name, FEEDBURNER_BrowserFriendly_QNAME)){
404           ret.setBrowserFriendly(e.getTextContent());
405         }else if(same(name, FEEDBURNER_OrigLink_QNAME)){
406           ret.setOrigLink(e.getTextContent());
407         }
408       }
409     }
410     return ret;
411   }
412 
413   /***
414    * Extracts the slash extension elements from the input list into an {@link SlashExtension}
415    * object. <br/>
416    * The extracted elements will be removed from the original input list.
417    * <br/>
418    * see http://web.resource.org/rss/1.0/modules/slash/ these
419    * extension elements
420    * @param otherElements - any elements
421    * @return an {@link SlashExtension} object
422    * @throws YarfrawException 
423    */
424   @SuppressWarnings("unchecked")
425   public static SlashExtension extractSlashExtension(List<Element> otherElements) throws YarfrawException {
426     SlashExtension ret = new SlashExtension();
427     try {
428       if(otherElements != null){
429         Iterator<Element> it = otherElements.iterator();
430         Unmarshaller u = getContext(ContextEnum.SLASH).createUnmarshaller();
431         while(it.hasNext()){
432           Element e = it.next();
433           if(e == null){
434             continue;
435           }
436           QName name = new QName(e.getNamespaceURI(), e.getLocalName());
437           if(same(name, SLASH_Comments_QNAME)){
438             ret.setComments(((JAXBElement<BigInteger>)u.unmarshal(e)).getValue());
439           }else if(same(name, SLASH_Department_QNAME)){
440             ret.setDepartment(e.getTextContent());
441           }else if(same(name, SLASH_HitParade_QNAME)){
442             ret.setHitParade(e.getTextContent());
443           }else if(same(name, SLASH_Section_QNAME)){
444             ret.setSection(e.getTextContent());
445           }
446         }
447       }
448     }
449     catch (JAXBException e) {
450       throw new YarfrawException("unable to unmarshal element", e);
451     }
452 
453     return ret;
454   }
455   
456   /***
457    * Extracts the well-formed web extension elements from the input list into an {@link BloggerExtension}
458    * object. <br/>
459    * The extracted elements will be removed from the original input list.
460    * <br/>
461    * see http://code.blogger.com/archives/atom-docs.html#extensions about these
462    * extension elements
463    * @param otherElements - any elements
464    * @return an {@link BloggerExtension} object
465    * @throws YarfrawException 
466    */
467   public static BloggerExtension extractBloggerExtension(List<Element> otherElements) throws YarfrawException {
468     BloggerExtension ret = new BloggerExtension();
469       if(otherElements != null){
470         Iterator<Element> it = otherElements.iterator();
471         while(it.hasNext()){
472           Element e = it.next();
473           if(e == null){
474             continue;
475           }
476           QName name = new QName(e.getNamespaceURI(), e.getLocalName());
477           if(same(name, BLOGGER_ConvertLineBreaks_QNAME)){
478             if(e.getTextContent() != null){
479               ret.setConvertLineBreaks(Boolean.valueOf(e.getTextContent()));
480             }
481           }else if(same(name, BLOGGER_Draft_QNAME)){
482             if(e.getTextContent() != null){
483               ret.setDraft(Boolean.valueOf(e.getTextContent()));
484             }
485           }
486         }
487       }
488     return ret;
489   }
490   
491   /***
492    * Extracts the well-formed web extension elements from the input list into an {@link SyndicationExtension}
493    * object. <br/>
494    * The extracted elements will be removed from the original input list.
495    * <br/>
496    * see http://web.resource.org/rss/1.0/modules/syndication/ about these
497    * extension elements
498    * @param otherElements - any elements
499    * @return an {@link SyndicationExtension} object
500    * @throws YarfrawException 
501    */
502   @SuppressWarnings("unchecked")
503   public static SyndicationExtension extractSyndicationExtension(List<Element> otherElements) throws YarfrawException {
504     SyndicationExtension ret = new SyndicationExtension();
505     try {
506       if(otherElements != null){
507         Iterator<Element> it = otherElements.iterator();
508         Unmarshaller u = getContext(ContextEnum.SY).createUnmarshaller();
509         while(it.hasNext()){
510           Element e = it.next();
511           if(e == null){
512             continue;
513           }
514           QName name = new QName(e.getNamespaceURI(), e.getLocalName());
515           if(same(name, SY_UpdateBase_QNAME)){
516             ret.setUpdateBase(e.getTextContent());
517             it.remove();
518           }else if(same(name, SY_UpdateFrequency_QNAME)){
519             ret.setUpdateFrequency(((JAXBElement<BigInteger>)u.unmarshal(e)).getValue());
520             it.remove();
521           }else if(same(name, SY_UpdatePeriod_QNAME)){
522             ret.setUpdatePeriod(((JAXBElement<UpdatePeriodEnum>)u.unmarshal(e)).getValue());
523             it.remove();
524           }
525         }
526       }
527     }catch (Exception e) {
528       throw new YarfrawException("unable to unmarshal element", e);
529     }
530     return ret;
531   }
532   
533   /***
534    * Extracts the googlebase extension elements from the input list into an {@link GoogleBaseExtension}
535    * object.
536    * <br/>
537    * see http://www.apple.com/itunes/store/podcaststechspecs.html about these
538    * extension elements
539    * @param otherElements - any elements
540    * @return an {@link GoogleBaseExtension} object
541    * @throws YarfrawException 
542    */
543   @SuppressWarnings("unchecked")
544   public static GoogleBaseExtension extractGoogleBaseExtension(List<Element> otherElements) throws YarfrawException {
545     GoogleBaseExtension ret = new GoogleBaseExtension();
546     try{
547       if(otherElements != null){
548         Unmarshaller u = JAXBContext.newInstance(GOOGLEBASE_JAXB_CONTEXT).createUnmarshaller();
549         Iterator<Element> it = otherElements.iterator();
550         while(it.hasNext()){
551           Element e = it.next();
552           if(e == null){
553             continue;
554           }
555           QName name = new QName(e.getNamespaceURI(), e.getLocalName());
556           if(same(name, GOOGLEBASE_Actor_QNAME)){
557             ret.getActor().add(e.getTextContent());
558             it.remove();
559           }else if(same(name, GOOGLEBASE_Agent_QNAME)){
560             ret.getAgent().add(e.getTextContent());
561             it.remove();
562           }else if(same(name, GOOGLEBASE_Age_QNAME)){
563             ret.setAge(e.getTextContent() == null ? null : Short.valueOf(e.getTextContent()));
564             it.remove();
565           }else if(same(name, GOOGLEBASE_ApparelType_QNAME)){
566             ret.setApparelType(e.getTextContent());
567             it.remove();
568           }else if(same(name, GOOGLEBASE_Area_QNAME)){
569             ret.setArea(e.getTextContent());
570             it.remove();
571           }else if(same(name, GOOGLEBASE_Artist_QNAME)){
572             ret.getArtist().add(e.getTextContent());
573             it.remove();
574           }else if(same(name, GOOGLEBASE_Author_QNAME)){
575             ret.getAuthor().add(e.getTextContent());
576             it.remove();
577           }else if(same(name, GOOGLEBASE_Bathrooms_QNAME)){
578             ret.setBathrooms(e.getTextContent() == null ? null : new BigDecimal(e.getTextContent()));
579             it.remove();
580           }else if(same(name, GOOGLEBASE_Bedrooms_QNAME)){
581             ret.setBedrooms(e.getTextContent() == null ? null : Short.valueOf(e.getTextContent()));
582             it.remove();
583           }else if(same(name, GOOGLEBASE_Brand_QNAME)){
584             ret.setBrand(e.getTextContent());
585             it.remove();
586           }else if(same(name, GOOGLEBASE_Color_QNAME)){
587             ret.getColor().add(e.getTextContent());
588             it.remove();
589           }else if(same(name, GOOGLEBASE_Condition_QNAME)){
590             ret.setCondition(e.getTextContent());
591             it.remove();
592           }else if(same(name, GOOGLEBASE_CourseDateRange_QNAME)){
593             DateTimeRangeType d = ((JAXBElement<DateTimeRangeType>)u.unmarshal(e)).getValue();
594             ret.setCourseDateRange(d);
595             it.remove();
596           }else if(same(name, GOOGLEBASE_CourseNumber_QNAME)){
597             ret.setCourseNumber(e.getTextContent());
598             it.remove();
599           }else if(same(name, GOOGLEBASE_CourseTimes_QNAME)){
600             ret.setCourseTimes(e.getTextContent());
601             it.remove();
602           }else if(same(name, GOOGLEBASE_Currency_QNAME)){
603             ret.setCurrency(((JAXBElement<CurrencyCodeEnumeration>)u.unmarshal(e)).getValue());
604             it.remove();
605           }else if(same(name, GOOGLEBASE_DeliveryNotes_QNAME)){
606             ret.setDeliveryNotes(e.getTextContent());
607             it.remove();
608           }else if(same(name, GOOGLEBASE_DeliveryRadius_QNAME)){
609             ret.setDeliveryRadius(e.getTextContent());
610             it.remove();
611           }else if(same(name, GOOGLEBASE_DevelopmentStatus_QNAME)){
612             ret.setDevelopmentStatus(e.getTextContent());
613             it.remove();
614           }else if(same(name, GOOGLEBASE_Education_QNAME)){
615             ret.getEducation().add(e.getTextContent());
616             it.remove();
617           }else if(same(name, GOOGLEBASE_Employer_QNAME)){
618             ret.getEmployer().add(e.getTextContent());
619             it.remove();
620           }else if(same(name, GOOGLEBASE_Ethnicity_QNAME)){
621             ret.getEthnicity().add(e.getTextContent());
622             it.remove();
623           }else if(same(name, GOOGLEBASE_EventDateRange_QNAME)){
624             DateTimeRangeType d = ((JAXBElement<DateTimeRangeType>)u.unmarshal(e)).getValue();
625             ret.setEventDateRange(d);
626             it.remove();
627           }else if(same(name, GOOGLEBASE_ExpirationDate_QNAME)){
628             XMLGregorianCalendar d = ((JAXBElement<XMLGregorianCalendar>)u.unmarshal(e)).getValue();
629             ret.setExpirationDate(d);
630             it.remove();
631           }else if(same(name, GOOGLEBASE_ExpirationDateTime_QNAME)){
632             XMLGregorianCalendar d = ((JAXBElement<XMLGregorianCalendar>)u.unmarshal(e)).getValue();
633             ret.setExpirationDateTime(d);
634             it.remove();
635           }else if(same(name, GOOGLEBASE_Format_QNAME)){
636             ret.getFormat().add(e.getTextContent());
637             it.remove();
638           }else if(same(name, GOOGLEBASE_ForSale_QNAME)){
639             ret.setForSale(((JAXBElement<Boolean>)u.unmarshal(e)).getValue());
640             it.remove();
641           }else if(same(name, GOOGLEBASE_FromLocation_QNAME)){
642             ret.setFromLocation(e.getTextContent());
643             it.remove();
644           }else if(same(name, GOOGLEBASE_Gender_QNAME)){
645             ret.setGender(((JAXBElement<GenderEnumeration>)u.unmarshal(e)).getValue());
646             it.remove();
647           }else if(same(name, GOOGLEBASE_HoaDues_QNAME)){
648             ret.setHoaDues(((JAXBElement<BigDecimal>)u.unmarshal(e)).getValue());
649             it.remove();
650           }else if(same(name, GOOGLEBASE_Id_QNAME)){
651             ret.setId(e.getTextContent());
652             it.remove();
653           }else if(same(name, GOOGLEBASE_ImageLink_QNAME)){
654             ret.getImageLink().add(e.getTextContent());
655             it.remove();
656           }else if(same(name, GOOGLEBASE_ImmigrationStatus_QNAME)){
657             ret.setImmigrationStatus(e.getTextContent());
658             it.remove();
659           }else if(same(name, GOOGLEBASE_InterestedIn_QNAME)){
660             ret.setInterestedIn(e.getTextContent());
661             it.remove();
662           }else if(same(name, GOOGLEBASE_Isbn_QNAME)){
663             ret.setIsbn(e.getTextContent());
664             it.remove();
665           }else if(same(name, GOOGLEBASE_JobFunction_QNAME)){
666             ret.getJobFunction().add(e.getTextContent());
667             it.remove();
668           }else if(same(name, GOOGLEBASE_JobIndustry_QNAME)){
669             ret.getJobIndustry().add(e.getTextContent());
670             it.remove();
671           }else if(same(name, GOOGLEBASE_JobType_QNAME)){
672             ret.getJobType().add(e.getTextContent());
673             it.remove();
674           }else if(same(name, GOOGLEBASE_Label_QNAME)){
675             ret.getLabel().add(e.getTextContent());
676             it.remove();
677           }else if(same(name, GOOGLEBASE_License_QNAME)){
678             ret.getLicense().add(e.getTextContent());
679             it.remove();
680           }else if(same(name, GOOGLEBASE_ListingType_QNAME)){
681             ret.getListingType().add(e.getTextContent());
682             it.remove();
683           }else if(same(name, GOOGLEBASE_Location_QNAME)){
684             ret.setLocation(e.getTextContent());
685             it.remove();
686           }else if(same(name, GOOGLEBASE_Make_QNAME)){
687             ret.setMake(e.getTextContent());
688             it.remove();
689           }else if(same(name, GOOGLEBASE_Manufacturer_QNAME)){
690             ret.setManufacturer(e.getTextContent());
691             it.remove();
692           }else if(same(name, GOOGLEBASE_ManufacturerId_QNAME)){
693             ret.setManufacturerId(e.getTextContent());
694             it.remove();
695           }else if(same(name, GOOGLEBASE_MaritalStatus_QNAME)){
696             ret.setMaritalStatus(e.getTextContent());
697             it.remove();
698           }else if(same(name, GOOGLEBASE_Megapixels_QNAME)){
699             ret.setMegapixels(e.getTextContent());
700             it.remove();
701           }else if(same(name, GOOGLEBASE_Memory_QNAME)){
702             ret.setMemory(e.getTextContent());
703             it.remove();
704           }else if(same(name, GOOGLEBASE_Mileage_QNAME)){
705             ret.setMileage(e.getTextContent());
706             it.remove();
707           }else if(same(name, GOOGLEBASE_Model_QNAME)){
708             ret.setModel(e.getTextContent());
709             it.remove();
710           }else if(same(name, GOOGLEBASE_ModelNumber_QNAME)){
711             ret.setModelNumber(e.getTextContent());
712             it.remove();
713           }else if(same(name, GOOGLEBASE_NameOfItemReviewed_QNAME)){
714             ret.setNameOfItemReviewed(e.getTextContent());
715             it.remove();
716           }else if(same(name, GOOGLEBASE_NewsSource_QNAME)){
717             ret.setNewsSource(e.getTextContent());
718             it.remove();
719           }else if(same(name, GOOGLEBASE_Occupation_QNAME)){
720             ret.setOccupation(e.getTextContent());
721             it.remove();
722           }else if(same(name, GOOGLEBASE_OperatingSystems_QNAME)){
723             ret.setOperatingSystems(e.getTextContent());
724             it.remove();
725           }else if(same(name, GOOGLEBASE_Pages_QNAME)){
726             ret.setPages(((JAXBElement<BigInteger>)u.unmarshal(e)).getValue());
727             it.remove();
728           }else if(same(name, GOOGLEBASE_PaymentAccepted_QNAME)){
729             ret.getPaymentAccepted().add(((JAXBElement<PaymentMethodEnumeration>)u.unmarshal(e)).getValue());
730             it.remove();
731           }else if(same(name, GOOGLEBASE_PaymentNotes_QNAME)){
732             ret.setPaymentNotes(e.getTextContent());
733             it.remove();
734           }else if(same(name, GOOGLEBASE_Pickup_QNAME)){
735             ret.setPickup(((JAXBElement<Boolean>)u.unmarshal(e)).getValue());
736             it.remove();
737           }else if(same(name, GOOGLEBASE_Price_QNAME)){
738             ret.setPrice(e.getTextContent());
739             it.remove();
740           }else if(same(name, GOOGLEBASE_PriceType_QNAME)){
741             ret.setPriceType(((JAXBElement<PriceTypeEnumeration>)u.unmarshal(e)).getValue());
742             it.remove();
743           }else if(same(name, GOOGLEBASE_ProcessorSpeed_QNAME)){
744             ret.setProcessorSpeed(e.getTextContent());
745             it.remove();
746           }else if(same(name, GOOGLEBASE_ProductType_QNAME)){
747             ret.getProductType().add(e.getTextContent());
748             it.remove();
749           }else if(same(name, GOOGLEBASE_ProgrammingLanguage_QNAME)){
750             ret.getProgrammingLanguage().add(e.getTextContent());
751             it.remove();
752           }else if(same(name, GOOGLEBASE_PropertyType_QNAME)){
753             ret.getPropertyType().add(e.getTextContent());
754             it.remove();
755           }else if(same(name, GOOGLEBASE_PublicationName_QNAME)){
756             ret.setPublicationName(e.getTextContent());
757             it.remove();
758           }else if(same(name, GOOGLEBASE_PublicationVolume_QNAME)){
759             ret.setPublicationVolume(e.getTextContent());
760             it.remove();
761           }else if(same(name, GOOGLEBASE_PublishDate_QNAME)){
762             ret.setPublishDate(((JAXBElement<XMLGregorianCalendar>)u.unmarshal(e)).getValue());
763             it.remove();
764           }else if(same(name, GOOGLEBASE_Quantity_QNAME)){
765             ret.setQuantity(((JAXBElement<BigInteger>)u.unmarshal(e)).getValue());
766             it.remove();
767           }else if(same(name, GOOGLEBASE_Rating_QNAME)){
768             ret.setRating(e.getTextContent());
769             it.remove();
770           }else if(same(name, GOOGLEBASE_RatingType_QNAME)){
771             ret.setRatingType(e.getTextContent());
772             it.remove();
773           }else if(same(name, GOOGLEBASE_RelatedLink_QNAME)){
774             ret.getRelatedLink().add(e.getTextContent());
775             it.remove();
776           }else if(same(name, GOOGLEBASE_ReviewerType_QNAME)){
777             ret.setReviewerType(e.getTextContent());
778             it.remove();
779           }else if(same(name, GOOGLEBASE_ReviewType_QNAME)){
780             ret.setReviewType(e.getTextContent());
781             it.remove();
782           }else if(same(name, GOOGLEBASE_Salary_QNAME)){
783             ret.setSalary(((JAXBElement<BigDecimal>)u.unmarshal(e)).getValue());
784             it.remove();
785           }else if(same(name, GOOGLEBASE_SalaryType_QNAME)){
786             ret.setSalaryType(((JAXBElement<PriceTypeEnumeration>)u.unmarshal(e)).getValue());
787             it.remove();
788           }else if(same(name, GOOGLEBASE_SchoolDistrict_QNAME)){
789             ret.setSchoolDistrict(e.getTextContent());
790             it.remove();
791           }else if(same(name, GOOGLEBASE_ServiceType_QNAME)){
792             ret.setServiceType(e.getTextContent());
793             it.remove();
794           }else if(same(name, GOOGLEBASE_SexualOrientation_QNAME)){ //what the hell?
795             ret.setSexualOrientation(e.getTextContent());
796             it.remove();
797           }else if(same(name, GOOGLEBASE_Shipping_QNAME)){
798             ret.getShipping().add(((JAXBElement<ShippingType>)u.unmarshal(e)).getValue());
799             it.remove();
800           }else if(same(name, GOOGLEBASE_Size_QNAME)){
801             ret.getSize().add(e.getTextContent());
802             it.remove();
803           }else if(same(name, GOOGLEBASE_SquareFootage_QNAME)){
804             ret.getSquareFootage().add(e.getTextContent());
805             it.remove();
806           }else if(same(name, GOOGLEBASE_Subject_QNAME)){
807             ret.getSubject().add(e.getTextContent());
808             it.remove();
809           }else if(same(name, GOOGLEBASE_SubjectArea_QNAME)){
810             ret.getSubjectArea().add(e.getTextContent());
811             it.remove();
812           }else if(same(name, GOOGLEBASE_TaxPercent_QNAME)){
813             ret.setTaxPercent(((JAXBElement<BigDecimal>)u.unmarshal(e)).getValue());
814             it.remove();
815           }else if(same(name, GOOGLEBASE_TaxRegion_QNAME)){
816             ret.setTaxRegion(e.getTextContent());
817             it.remove();
818           }else if(same(name, GOOGLEBASE_ToLocation_QNAME)){
819             ret.setToLocation(e.getTextContent());
820             it.remove();
821           }else if(same(name, GOOGLEBASE_TravelDateRange_QNAME)){
822             DateTimeRangeType d = ((JAXBElement<DateTimeRangeType>)u.unmarshal(e)).getValue();
823             ret.setTravelDateRange(d);
824             it.remove();
825           }else if(same(name, GOOGLEBASE_University_QNAME)){
826             ret.setUniversity(e.getTextContent());
827             it.remove();
828           }else if(same(name, GOOGLEBASE_Upc_QNAME)){
829             ret.setUpc(e.getTextContent());
830             it.remove();
831           }else if(same(name, GOOGLEBASE_UrlOfItemReviewed_QNAME)){
832             ret.setUrlOfItemReviewed(e.getTextContent());
833             it.remove();
834           }else if(same(name, GOOGLEBASE_VehicleType_QNAME)){
835             ret.getVehicleType().add(e.getTextContent());
836             it.remove();
837           }else if(same(name, GOOGLEBASE_Vin_QNAME)){
838             ret.setVin(e.getTextContent());
839             it.remove();
840           }else if(same(name, GOOGLEBASE_Weight_QNAME)){
841             ret.setWeight(e.getTextContent());
842             it.remove();
843           }else if(same(name, GOOGLEBASE_Year_QNAME)){
844             ret.setYear(((JAXBElement<XMLGregorianCalendar>)u.unmarshal(e)).getValue());
845             it.remove();
846           }else if(HTTP_BASE_GOOGLE_COM_CNS_1_0.equals(e.getNamespaceURI())){
847             ret.getAny().add(e);
848             it.remove();
849           }
850         }
851       }
852     }catch (JAXBException e) {
853       throw new YarfrawException("unable to unmarshal element", e);
854     }
855     return ret;
856   }
857 
858   /***
859    * Extracts the Georss extension elements from the input list into an {@link GeoRssExtension}
860    * object.<br/>
861    * The extracted elements will be removed from the original input list.
862    * 
863    * <br/>
864    * see http://georss.org/ about these
865    * extension elements
866    * @param otherElements - any elements
867    * @return an {@link GeoRssExtension} object
868    * @throws YarfrawException 
869    */
870   @SuppressWarnings("unchecked")
871   public static GeoRssExtension extractGeoRssExtension(List<Element> otherElements) throws YarfrawException {
872     GeoRssExtension ret = new GeoRssExtension();
873     try{
874       if(otherElements != null){
875         Unmarshaller u = JAXBContext.newInstance(GEORSS_JAXB_CONTEXT).createUnmarshaller();
876         Iterator<Element> it = otherElements.iterator();
877         while(it.hasNext()){
878           Element e = it.next();
879           if(e == null){
880             continue;
881           }
882           QName name = new QName(e.getNamespaceURI(), e.getLocalName());
883           if(same(name, GEORSS_WHERE_QNAME)){
884             Where copy = ((JAXBElement<Where>)u.unmarshal(e)).getValue();
885             ret.setWhere(copy);
886             it.remove();
887           }else if(same(name, GEORSS_BOX_QNAME)){
888             SimplePositionType pos = ((JAXBElement<SimplePositionType>)u.unmarshal(e)).getValue();
889             ret.setBox(pos);
890             it.remove();
891           }else if(same(name, GEORSS_LINE_QNAME)){
892             SimplePositionType pos = ((JAXBElement<SimplePositionType>)u.unmarshal(e)).getValue();
893             ret.setLine(pos);
894             it.remove();
895           }else if(same(name, GEORSS_POINT_QNAME)){
896             SimplePositionType pos = ((JAXBElement<SimplePositionType>)u.unmarshal(e)).getValue();
897             ret.setPoint(pos);
898             it.remove();
899           }else if(same(name, GEORSS_POLYGON_QNAME)){
900             SimplePositionType pos = ((JAXBElement<SimplePositionType>)u.unmarshal(e)).getValue();
901             ret.setPolygon(pos);
902             it.remove();
903           }
904         }
905       }
906     }catch (JAXBException e) {
907       throw new YarfrawException("unable to unmarshal element", e);
908     }
909     return ret;
910   }
911   
912   /***
913    * Extracts the mrss extension elements from the input list into an {@link MrssExtension}
914    * object.<br/>
915    * The extracted elements will be removed from the original input list.
916    * 
917    * <br/>
918    * see http://search.yahoo.com/mrss about these
919    * extension elements
920    * @param otherElements - any elements
921    * @return an {@link MrssExtension} object
922    * @throws YarfrawException 
923    */
924   @SuppressWarnings("unchecked")
925   public static MrssExtension extractMrssExtension(List<Element> otherElements) throws YarfrawException {
926     MrssExtension ret = new MrssExtension();
927     try{
928       if(otherElements != null){
929         Unmarshaller u = JAXBContext.newInstance(MRSS_JAXB_CONTEXT).createUnmarshaller();
930         Iterator<Element> it = otherElements.iterator();
931         while(it.hasNext()){
932           Element e = it.next();
933           if(e == null){
934             continue;
935           }
936           QName name = new QName(e.getNamespaceURI(), e.getLocalName());
937           if(same(name, MRSS_CATEGORY_QNAME)){
938             MrssCategoryType cat = ((JAXBElement<MrssCategoryType>)u.unmarshal(e)).getValue();
939             ret.getCategory().add(cat);
940             it.remove();
941           }else if(same(name, MRSS_CONTENT_QNAME)){
942             MrssContentType content = ((JAXBElement<MrssContentType>)u.unmarshal(e)).getValue();
943             ret.getContent().add(content);
944             it.remove();
945           }else if(same(name, MRSS_COPYRIGHT_QNAME)){
946             MrssCopyrightType copy = ((JAXBElement<MrssCopyrightType>)u.unmarshal(e)).getValue();
947             ret.setCopyright(copy);
948             it.remove();
949           }else if(same(name, MRSS_CREDIT_QNAME)){
950             MrssCreditType copy = ((JAXBElement<MrssCreditType>)u.unmarshal(e)).getValue();
951             ret.getCredit().add(copy);
952             it.remove();
953           }else if(same(name, MRSS_DESCRIPTION_QNAME)){
954             MrssDescriptionType copy = ((JAXBElement<MrssDescriptionType>)u.unmarshal(e)).getValue();
955             ret.setDescription(copy);
956             it.remove();
957           }else if(same(name, MRSS_GROUP_QNAME)){
958             MrssGroupType copy = ((JAXBElement<MrssGroupType>)u.unmarshal(e)).getValue();
959             ret.getGroup().add(copy);
960             it.remove();
961           }else if(same(name, MRSS_HASH_QNAME)){
962             MrssHashType copy = ((JAXBElement<MrssHashType>)u.unmarshal(e)).getValue();
963             ret.setHash(copy);
964             it.remove();
965           }else if(same(name, MRSS_KEYWORDS_QNAME)){
966             ret.setKeywords(e.getTextContent());
967             it.remove();
968           }else if(same(name, MRSS_PLAYER_QNAME)){
969             MrssPlayerType copy = ((JAXBElement<MrssPlayerType>)u.unmarshal(e)).getValue();
970             ret.setPlayer(copy);
971             it.remove();
972           }else if(same(name, MRSS_RATING_QNAME)){
973             MrssRatingType copy = ((JAXBElement<MrssRatingType>)u.unmarshal(e)).getValue();
974             ret.setRating(copy);
975             it.remove();
976           }else if(same(name, MRSS_RESTRICTION_QNAME)){
977             MrssRestrictionType copy = ((JAXBElement<MrssRestrictionType>)u.unmarshal(e)).getValue();
978             ret.setRestriction(copy);
979             it.remove();
980           }else if(same(name, MRSS_TEXT_QNAME)){
981             MrssTextType copy = ((JAXBElement<MrssTextType>)u.unmarshal(e)).getValue();
982             ret.setText(copy);
983             it.remove();
984           }else if(same(name, MRSS_THUMBNAIL_QNAME)){
985             MrssThumbnailType copy = ((JAXBElement<MrssThumbnailType>)u.unmarshal(e)).getValue();
986             ret.setThumbnail(copy);
987             it.remove();
988           }else if(same(name, MRSS_TITLE_QNAME)){
989             MrssTitleType copy = ((JAXBElement<MrssTitleType>)u.unmarshal(e)).getValue();
990             ret.setTitle(copy);
991             it.remove();
992           }
993         }
994       }
995     }catch (JAXBException e) {
996       throw new YarfrawException("unable to unmarshal element", e);
997     }
998     return ret;
999   }
1000   /***
1001    * Converts the input {@link ItunesExtension} object to an element list.
1002    * <br/>
1003    * see http://www.apple.com/itunes/store/podcaststechspecs.html about these
1004    * extension elements
1005    * 
1006    * @param extensionObject an valid {@link ItunesExtension} object
1007    * @return a list of elements representing all the elements in the input extension object
1008    * @throws YarfrawException if conversion failed
1009    */
1010   public static List<Element> toItunesElements(ItunesExtension extensionObject)
1011   throws YarfrawException{
1012     return toElements(extensionObject, ContextEnum.ITUNES);
1013   }
1014 
1015   /***
1016    * Converts the input {@link GeoRssExtension} object to an element list.
1017    * <br/>
1018    * see http://georss.org/ about these
1019    * extension elements
1020    * 
1021    * @param extensionObject an valid {@link GeoRssExtension} object
1022    * @return a list of elements representing all the elements in the input extension object
1023    * @throws YarfrawException if conversion failed
1024    */
1025   public static List<Element> toGeoRssElements(GeoRssExtension extensionObject)
1026   throws YarfrawException{
1027     return toElements(extensionObject, ContextEnum.GEORSS);
1028   }
1029   
1030 
1031   /***
1032    * Converts the input {@link GoogleBaseExtension} object to an element list.
1033    * <br/>
1034    * see http://base.google.com/support/bin/answer.py?answer=58085&hl=en about these
1035    * extension elements
1036    * 
1037    * @param extensionObject an valid {@link GoogleBaseExtension} object
1038    * @return a list of elements representing all the elements in the input extension object
1039    * @throws YarfrawException if conversion failed
1040    */
1041   public static List<Element> toGoogleBaseElements(GoogleBaseExtension extensionObject)
1042   throws YarfrawException{
1043     //XXX: not sure why i have to do this to make it marshall
1044     JAXBElement<GoogleBaseExtension> jaxb = GOOGLEBASE_FACTORY.createGoogleBaseExtension(extensionObject);
1045     return toElements(jaxb, ContextEnum.GOOGLEBASE);
1046   }
1047   
1048   /***
1049    * Converts the input {@link MrssExtension} object to an element list.
1050    * <br/>
1051    * see http://search.yahoo.com/mrss about these
1052    * extension elements
1053    * 
1054    * @param extensionObject an valid {@link MrssExtension} object
1055    * @return a list of elements representing all the elements in the input extension object
1056    * @throws YarfrawException if conversion failed
1057    */
1058   public static List<Element> toMrssElements(MrssExtension extensionObject)
1059   throws YarfrawException{
1060     return toElements(extensionObject, ContextEnum.MRSS);
1061   }
1062 
1063   /***
1064    * Converts the input {@link WellFormedWebExtension} object to an element list.
1065    * <br/>
1066    * see http://wellformedweb.org/news/wfw_namespace_elements about these
1067    * extension elements
1068    * 
1069    * @param extensionObject an valid {@link WellFormedWebExtension} object
1070    * @return a list of elements representing all the elements in the input extension object
1071    * @throws YarfrawException if conversion failed
1072    */
1073   public static List<Element> toWellFormedWebElements(WellFormedWebExtension extensionObject)
1074   throws YarfrawException{
1075     return toElements(extensionObject, ContextEnum.WFW);
1076   }
1077   
1078   /***
1079    * Converts the input {@link DublinCoreExtension} object to an element list.
1080    * <br/>
1081    * see http://dublincore.org/documents/2002/07/31/dcmes-xml/ about these
1082    * extension elements
1083    * 
1084    * @param extensionObject an valid {@link DublinCoreExtension} object
1085    * @return a list of elements representing all the elements in the input extension object
1086    * @throws YarfrawException if conversion failed
1087    */
1088   public static List<Element> toDublinCoreElements(DublinCoreExtension extensionObject)
1089   throws YarfrawException{
1090     return toElements(extensionObject, ContextEnum.DC);
1091   }
1092   
1093   /***
1094    * Converts the input {@link SyndicationExtension} object to an element list.
1095    * <br/>
1096    * see http://web.resource.org/rss/1.0/modules/syndication/ about these
1097    * extension elements
1098    * 
1099    * @param extensionObject an valid {@link SyndicationExtension} object
1100    * @return a list of elements representing all the elements in the input extension object
1101    * @throws YarfrawException if conversion failed
1102    */
1103   public static List<Element> toSyndicationElements(SyndicationExtension extensionObject)
1104   throws YarfrawException{
1105     return toElements(extensionObject, ContextEnum.SY);
1106   }
1107   
1108   /***
1109    * Converts the input {@link BloggerExtension} object to an element list.
1110    * <br/>
1111    * see http://code.blogger.com/archives/atom-docs.html#extensions about these
1112    * extension elements
1113    * 
1114    * @param extensionObject an valid {@link BloggerExtension} object
1115    * @return a list of elements representing all the elements in the input extension object
1116    * @throws YarfrawException if conversion failed
1117    */
1118   public static List<Element> toBloggerAtomElements(BloggerExtension extensionObject)
1119   throws YarfrawException{
1120     return toElements(extensionObject, ContextEnum.BLOGGER);
1121   }
1122 
1123   /***
1124    * Converts the input {@link AdminExtension} object to an element list.
1125    * <br/>
1126    * see http://web.resource.org/rss/1.0/modules/admin/ about these
1127    * extension elements
1128    * 
1129    * @param extensionObject an valid {@link AdminExtension} object
1130    * @return a list of elements representing all the elements in the input extension object
1131    * @throws YarfrawException if conversion failed
1132    */
1133   public static List<Element> toAdminAtomElements(AdminExtension extensionObject)
1134   throws YarfrawException{
1135     return toElements(extensionObject, ContextEnum.ADMIN);
1136   }
1137 
1138   /***
1139    * Converts the input {@link FeedburnerExtension} object to an element list.
1140    * <br/>
1141    * see http://web.resource.org/rss/1.0/modules/admin/ about these
1142    * extension elements
1143    * 
1144    * @param extensionObject an valid {@link FeedburnerExtension} object
1145    * @return a list of elements representing all the elements in the input extension object
1146    * @throws YarfrawException if conversion failed
1147    */
1148   public static List<Element> toFeedburnerElements(FeedburnerExtension extensionObject)
1149   throws YarfrawException{
1150     return toElements(extensionObject, ContextEnum.FEEDBURNER);
1151   }
1152 
1153   /***
1154    * Converts the input {@link FeedburnerExtension} object to an element list.
1155    * <br/>
1156    * see http://web.resource.org/rss/1.0/modules/admin/ about these
1157    * extension elements
1158    * 
1159    * @param extensionObject an valid {@link FeedburnerExtension} object
1160    * @return a list of elements representing all the elements in the input extension object
1161    * @throws YarfrawException if conversion failed
1162    */
1163   public static List<Element> toSlahsElements(SlashExtension extensionObject)
1164   throws YarfrawException{
1165     return toElements(extensionObject, ContextEnum.SLASH);
1166   }
1167   
1168   private static JAXBContext DC_CTX = null;
1169   private static JAXBContext GEORSS_CTX = null;
1170   private static JAXBContext GOOGLEBASE_CTX = null;
1171   private static JAXBContext ITUNES_CTX = null;
1172   private static JAXBContext MRSS_CTX = null;
1173   private static JAXBContext SY_CTX = null;
1174   private static JAXBContext WFW_CTX = null;
1175   private static JAXBContext BLOGGER_CTX = null;
1176   private static JAXBContext ADMIN_CTX = null;
1177   private static JAXBContext FEEDBURNER_CTX = null;
1178   private static JAXBContext SLASH_CTX = null;
1179   private static JAXBContext ATOM03_CTX = null;
1180   
1181   private static synchronized JAXBContext getContext(ContextEnum ctxEnum) throws JAXBException{
1182     if(ctxEnum == ContextEnum.DC){
1183       if(DC_CTX == null){
1184         DC_CTX = JAXBContext.newInstance(DUBLINCORE_JAXB_CONTEXT); 
1185       }
1186       return DC_CTX;
1187     }else if(ctxEnum == ContextEnum.ATOM03){
1188       if(ATOM03_CTX == null){
1189         ATOM03_CTX = JAXBContext.newInstance(ATOM03_JAXB_CONTEXT); 
1190       }
1191       return ATOM03_CTX;
1192     }else if(ctxEnum == ContextEnum.ADMIN){
1193       if(ADMIN_CTX == null){
1194         ADMIN_CTX = JAXBContext.newInstance(ADMIN_JAXB_CONTEXT); 
1195       }
1196       return ADMIN_CTX;
1197     }else if(ctxEnum == ContextEnum.BLOGGER){
1198       if(BLOGGER_CTX == null){
1199         BLOGGER_CTX = JAXBContext.newInstance(BLOGGER_JAXB_CONTEXT); 
1200       }
1201       return BLOGGER_CTX;
1202     }else if(ctxEnum == ContextEnum.FEEDBURNER){
1203       if(FEEDBURNER_CTX == null){
1204         FEEDBURNER_CTX = JAXBContext.newInstance(FEEDBURNER_JAXB_CONTEXT); 
1205       }
1206       return FEEDBURNER_CTX;
1207     }else if(ctxEnum == ContextEnum.SLASH){
1208       if(SLASH_CTX == null){
1209         SLASH_CTX = JAXBContext.newInstance(SLASH_JAXB_CONTEXT); 
1210       }
1211       return SLASH_CTX;
1212     }else if(ctxEnum == ContextEnum.GEORSS){
1213       if(GEORSS_CTX == null){
1214         GEORSS_CTX = JAXBContext.newInstance(GEORSS_JAXB_CONTEXT); 
1215       }
1216       return GEORSS_CTX;
1217     }else if(ctxEnum == ContextEnum.GOOGLEBASE){
1218       if(GOOGLEBASE_CTX == null){
1219         GOOGLEBASE_CTX = JAXBContext.newInstance(GOOGLEBASE_JAXB_CONTEXT);
1220       }
1221       return GOOGLEBASE_CTX;
1222     }else if(ctxEnum == ContextEnum.ITUNES){
1223       if(ITUNES_CTX == null){
1224         ITUNES_CTX = JAXBContext.newInstance(ITUNES_JAXB_CONTEXT);
1225       }
1226       return ITUNES_CTX;
1227     }else if(ctxEnum == ContextEnum.MRSS){
1228       if(MRSS_CTX == null){
1229         MRSS_CTX = JAXBContext.newInstance(MRSS_JAXB_CONTEXT);
1230       }
1231       return MRSS_CTX;
1232     }else if(ctxEnum == ContextEnum.SY){
1233       if(SY_CTX == null){
1234         SY_CTX = JAXBContext.newInstance(SY_JAXB_CONTEXT);
1235       }
1236       return SY_CTX;
1237     }else if(ctxEnum == ContextEnum.WFW){
1238       if(WFW_CTX == null){
1239         WFW_CTX = JAXBContext.newInstance(WFW_JAXB_CONTEXT);
1240       }
1241       return WFW_CTX;
1242     }
1243     
1244     throw new UnsupportedOperationException("Unknown JAXB context: "+ctxEnum);
1245   }
1246   
1247   private static List<Element> toElements(Object extensionObject, ContextEnum ctxEnum) throws YarfrawException {
1248     DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
1249     dbf.setNamespaceAware(true);
1250     List<Element> ret = new ArrayList<Element>();
1251     try {
1252       Document doc = dbf.newDocumentBuilder().newDocument();
1253       Marshaller m = getContext(ctxEnum).createMarshaller();
1254       m.setProperty(JAXBUtils.PREFIX_MAPPER_PROPERTY_NAME, JAXBUtils.getNamespacePrefixMapper(FeedFormat.RSS20));
1255       m.marshal(extensionObject, doc);
1256       Element e = doc.getDocumentElement();
1257       NodeList list =  e.getChildNodes();
1258       for(int i =0; i< list.getLength(); i++){
1259         Node n = list.item(i);
1260         if (n instanceof Element) {
1261           Element element = (Element) n;
1262           ret.add(element);
1263         }else {
1264           LOG.error("Ignore unexpected node "+n.getNodeName()+", this should not happen");
1265         }
1266       }
1267     }
1268     catch (ParserConfigurationException e) {
1269       throw new YarfrawException("Parserconfig exception", e);
1270     }
1271     catch (JAXBException e) {
1272       e.printStackTrace();
1273       throw new YarfrawException("JAXB exception", e);
1274     }
1275     return ret;
1276   }
1277   
1278 }