| /* |
| * Licensed to the Apache Software Foundation (ASF) under one or more |
| * contributor license agreements. The ASF licenses this file to You |
| * under the Apache License, Version 2.0 (the "License"); you may not |
| * use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. For additional information regarding |
| * copyright in this work, please see the NOTICE file in the top level |
| * directory of this distribution. |
| */ |
| package org.apache.abdera.converter; |
| |
| import java.lang.annotation.Annotation; |
| import java.lang.reflect.AccessibleObject; |
| import java.lang.reflect.AnnotatedElement; |
| import java.lang.reflect.Field; |
| import java.lang.reflect.Method; |
| import java.net.URI; |
| import java.net.URL; |
| import java.util.ArrayList; |
| import java.util.Calendar; |
| import java.util.Collection; |
| import java.util.Date; |
| import java.util.Dictionary; |
| import java.util.Enumeration; |
| import java.util.Iterator; |
| import java.util.List; |
| import java.util.Map; |
| |
| import org.apache.abdera.converter.annotation.BaseURI; |
| import org.apache.abdera.converter.annotation.Charset; |
| import org.apache.abdera.converter.annotation.EntityTag; |
| import org.apache.abdera.converter.annotation.Language; |
| import org.apache.abdera.converter.annotation.LastModified; |
| import org.apache.abdera.converter.annotation.Slug; |
| import org.apache.abdera.converter.impl.StringConverter; |
| import org.apache.abdera.i18n.iri.IRI; |
| import org.apache.abdera.model.AtomDate; |
| import org.apache.abdera.model.Base; |
| import org.apache.abdera.model.Document; |
| import org.apache.abdera.model.Element; |
| |
| @SuppressWarnings("unchecked") |
| public abstract class BaseConverter<T> |
| extends Converter<T> { |
| |
| protected abstract T create(ConversionContext context); |
| |
| protected void init( |
| Object source, |
| ObjectContext objectContext, |
| ConversionContext context, |
| T dest) {} |
| |
| protected void finish( |
| Object source, |
| ObjectContext objectContext, |
| ConversionContext context, |
| T dest) {} |
| |
| protected void process( |
| Object source, |
| ObjectContext |
| objectContext, |
| ConversionContext context, |
| Conventions conventions, |
| T dest, |
| AccessibleObject accessor) {} |
| |
| private Document getDocument(T obj) { |
| if (obj == null) return null; |
| Document doc = null; |
| if (obj instanceof Document) { |
| doc = (Document) obj; |
| } else if (obj instanceof Element) { |
| Element element = (Element) obj; |
| Document parent = element.getDocument(); |
| Element root = parent.getRoot(); |
| if (root.equals(element)) doc = parent; |
| } |
| return doc; |
| } |
| |
| @Override |
| public T convert( |
| Object source, |
| ObjectContext objectContext, |
| ConversionContext context) { |
| T dest = create(context); |
| init( |
| source, |
| objectContext, |
| context, |
| dest); |
| Conventions conventions = |
| ((ConventionConversionContext)context) |
| .getConventions(); |
| for (AccessibleObject accessor : objectContext.getAccessors()) { |
| if (dest instanceof Base && |
| accessor.isAnnotationPresent(Language.class) || |
| Language.class.equals(conventions.matchConvention(accessor))) { |
| Object value = eval(accessor,source); |
| ObjectContext valueContext = new ObjectContext(value,source,accessor); |
| StringConverter c = new StringConverter(); |
| StringBuffer buf = c.convert(value, valueContext, context); |
| if (buf != null) { |
| if (dest instanceof Document) ((Document)dest).setLanguage(buf.toString()); |
| else if (dest instanceof Element) ((Element)dest).setLanguage(buf.toString()); |
| } |
| } else if (dest instanceof Base && |
| accessor.isAnnotationPresent(BaseURI.class) || |
| BaseURI.class.equals(conventions.matchConvention(accessor))) { |
| |
| Object value = eval(accessor,source); |
| String iri = null; |
| if (value instanceof URI) { |
| iri = value.toString(); |
| } else if (value instanceof URL) { |
| iri = value.toString(); |
| } else if (value instanceof IRI) { |
| iri = value.toString(); |
| } else { |
| ObjectContext valueContext = new ObjectContext(value,source,accessor); |
| StringConverter c = new StringConverter(); |
| StringBuffer buf = c.convert(value, valueContext, context); |
| iri = buf.toString(); |
| } |
| if (iri != null) { |
| if (dest instanceof Document) ((Document)dest).setBaseUri(iri); |
| else if (dest instanceof Element) ((Element)dest).setBaseUri(iri); |
| } |
| } else if (accessor.isAnnotationPresent(Slug.class) || |
| Slug.class.equals(conventions.matchConvention(accessor))) { |
| Object value = eval(accessor,source); |
| ObjectContext valueContext = new ObjectContext(value,source,accessor); |
| StringConverter c = new StringConverter(); |
| StringBuffer buf = c.convert(value, valueContext, context); |
| Document doc = getDocument(dest); |
| if (doc != null && buf != null) doc.setSlug(buf.toString()); |
| } else if (accessor.isAnnotationPresent(LastModified.class) || |
| LastModified.class.equals(conventions.matchConvention(accessor))) { |
| Object value = eval(accessor,source); |
| Document doc = getDocument(dest); |
| if (doc != null) { |
| if (value instanceof Date) { |
| doc.setLastModified((Date)value); |
| } else if (value instanceof Calendar) { |
| Calendar cal = (Calendar)value; |
| doc.setLastModified(cal.getTime()); |
| } else if (value instanceof Long) { |
| Long l = (Long) value; |
| doc.setLastModified(new Date(l.longValue())); |
| } else if (value instanceof String) { |
| doc.setLastModified(AtomDate.parse((String)value)); |
| } else { |
| StringConverter s = new StringConverter(); |
| StringBuffer v = s.convert(source, objectContext, context); |
| if (v != null) doc.setLastModified(AtomDate.parse(v.toString())); |
| } |
| } |
| } else if (accessor.isAnnotationPresent(Charset.class) || |
| Charset.class.equals(conventions.matchConvention(accessor))) { |
| Object value = eval(accessor,source); |
| ObjectContext valueContext = new ObjectContext(value,source,accessor); |
| StringConverter c = new StringConverter(); |
| StringBuffer buf = c.convert(value, valueContext, context); |
| Document doc = getDocument(dest); |
| if (doc != null && buf != null) doc.setCharset(buf.toString()); |
| } else if (accessor.isAnnotationPresent(EntityTag.class) || |
| EntityTag.class.equals(conventions.matchConvention(accessor))) { |
| Document doc = getDocument(dest); |
| if (doc != null) { |
| Object value = eval(accessor,source); |
| if (value instanceof org.apache.abdera.util.EntityTag) { |
| doc.setEntityTag((org.apache.abdera.util.EntityTag)value); |
| } else { |
| ObjectContext valueContext = new ObjectContext(value,source,accessor); |
| StringConverter c = new StringConverter(); |
| StringBuffer buf = c.convert(value, valueContext, context); |
| if (buf != null) doc.setEntityTag(buf.toString()); |
| } |
| } |
| } else { |
| process(source, objectContext, context, conventions, dest, accessor); |
| } |
| } |
| finish( |
| source, |
| objectContext, |
| context, |
| dest); |
| return dest; |
| } |
| |
| protected Object eval(AccessibleObject accessor, Object parent) { |
| try { |
| if (accessor instanceof Field) |
| return ((Field)accessor).get(parent); |
| else if (accessor instanceof Method) |
| return ((Method)accessor).invoke(parent, new Object[0]); |
| else return null; |
| } catch (Throwable t) { |
| throw new ConversionException(t); |
| } |
| } |
| |
| protected boolean hasAnnotation( |
| AnnotatedElement item, |
| Class<? extends Annotation> annotation) { |
| return item.isAnnotationPresent(annotation); |
| } |
| |
| protected Object[] toArray(Object value) { |
| if (value == null) return new Object[0]; |
| if (value.getClass().isArray()) { |
| return (Object[])value; |
| } else if (value instanceof Collection) { |
| return ((Collection)value).toArray(); |
| } else if (value instanceof Map) { |
| return ((Map)value).values().toArray(); |
| } else if (value instanceof Dictionary) { |
| List<Object> list = new ArrayList<Object>(); |
| Enumeration e = ((Dictionary)value).elements(); |
| while(e.hasMoreElements()) list.add(e.nextElement()); |
| return list.toArray(); |
| } else if (value instanceof Iterator) { |
| List<Object> list = new ArrayList<Object>(); |
| Iterator i = (Iterator) value; |
| while(i.hasNext()) list.add(i.next()); |
| return list.toArray(); |
| } else if (value instanceof Enumeration) { |
| List<Object> list = new ArrayList<Object>(); |
| Enumeration e = (Enumeration) value; |
| while(e.hasMoreElements()) list.add(e.nextElement()); |
| return list.toArray(); |
| } else if (value instanceof Iterable) { |
| List<Object> list = new ArrayList<Object>(); |
| Iterable v = (Iterable) value; |
| Iterator i = v.iterator(); |
| while(i.hasNext()) list.add(i.next()); |
| return list.toArray(); |
| } else { |
| return new Object[] {value}; |
| } |
| } |
| } |