/* * This is a common dao with basic CRUD operations and is not limited to any * persistent layer implementation * * Copyright (C) 2009 Imran M Yousuf (imyousuf@smartitengineering.com) * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 3 of the License, or (at your option) any later version. * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ package com.smartitengineering.exim.impl.xml; import com.smartitengineering.exim.AssociationConfig.AssociationType; import com.smartitengineering.exim.ConfigRegistrar; import com.smartitengineering.exim.EximResourceConfig; import com.smartitengineering.exim.Exporter; import com.smartitengineering.util.simple.IOFactory; import com.smartitengineering.util.simple.reflection.ClassInstanceVisitorImpl; import com.smartitengineering.util.simple.reflection.ClassScanner; import com.smartitengineering.util.simple.reflection.Config; import com.smartitengineering.util.simple.reflection.VisitCallback; import java.io.IOException; import java.io.OutputStream; import java.lang.annotation.Annotation; import java.lang.reflect.Type; import java.util.HashMap; import java.util.List; import java.util.Map; import javax.xml.transform.OutputKeys; import javax.xml.transform.Transformer; import javax.xml.transform.TransformerConfigurationException; import javax.xml.transform.sax.SAXTransformerFactory; import javax.xml.transform.sax.TransformerHandler; import javax.xml.transform.stream.StreamResult; import org.xml.sax.SAXException; /** * * @author imyousuf * @since 0.4 */ public class XMLExporterImpl implements Exporter { private String encoding; private String indent; private String method; private static Map<AssociationType, ElementExporter> handlers; static { handlers = new HashMap<AssociationType, ElementExporter>( AssociationType.values().length); String packageName = ConfigRegistrar.class.getPackage().getName(); ClassScanner scanner = IOFactory.getDefaultClassScanner(); scanner.scan(new String[] {packageName}, new ClassInstanceVisitorImpl(IOFactory.getClassNameForVisitor( ElementExporter.class), new VisitCallback<Config>() { public void handle(Config config) { try { IOFactory.getClassFromVisitorName(config.getClassName()); } catch (Exception ex) { ex.printStackTrace(); } } })); } static void addHandler(AssociationType type, ElementExporter exporter) { handlers.put(type, exporter); } static ElementExporter getElementExporter(AssociationType type) { return handlers.get(type); } public XMLExporterImpl() { encoding = "UTF-8"; indent = "yes"; method = "xml"; } public boolean isExportSupported(Class clazz, Type genericType, Annotation[] annotations) { if (clazz == null) { return false; } AssociationType type = AssociationType.getAssociationType(clazz); if (type != null && type != AssociationType.TYPE_OBJECT && type != AssociationType.TYPE_ARRAY) { return true; } EximResourceConfig config = ConfigRegistrar.getConfigForClass( getComponentClass(clazz)); if (config != null) { return true; } return false; } public long getAfterExportLength(Object object, Class clazz, Type genericType, Annotation[] annotations) { return -1; } public void exportObject(Object object, Class clazz, Type genericType, Annotation[] annotations, OutputStream outputStream, Map<Object, List<Object>> headers) throws IOException { if (outputStream == null || clazz == null || object == null) { throw new IOException( "OutputStream or Object or Class can't be null!"); } try { SAXTransformerFactory factory = (SAXTransformerFactory) SAXTransformerFactory. newInstance(); TransformerHandler handler = factory.newTransformerHandler(); StreamResult result = new StreamResult(outputStream); Transformer transformer = handler.getTransformer(); transformer.setOutputProperty(OutputKeys.ENCODING, encoding); transformer.setOutputProperty(OutputKeys.INDENT, indent); transformer.setOutputProperty(OutputKeys.METHOD, method); handler.setResult(result); handler.startDocument(); try { AssociationType type = AssociationType.getAssociationType(clazz); ElementExporter exporter = getElementExporter(type); if (exporter == null) { throw new UnsupportedOperationException("Type not supported yet! - " + type); } exporter.exportElement(type, object, handler); } finally { handler.endDocument(); } } catch (SAXException ex) { throw new IOException(ex); } catch (TransformerConfigurationException ex) { throw new IOException(ex); } } public String getMediaType() { return "application/xml"; } public String getEncoding() { return encoding; } public void setEncoding(String encoding) { this.encoding = encoding; } public String getIndent() { return indent; } public void setIndent(String indent) { this.indent = indent; } public String getMethod() { return method; } public void setMethod(String method) { this.method = method; } private Class getComponentClass(Class clazz) { if (clazz == null) { throw new IllegalArgumentException(); } return clazz.isArray() ? clazz.getComponentType() : clazz; } }