Java tutorial
/** * Copyright 2008 The University of North Carolina at Chapel Hill * * Licensed 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. */ package edu.unc.lib.dl.fedora; import java.io.BufferedWriter; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileOutputStream; import java.io.FileWriter; import java.io.IOException; import java.io.OutputStreamWriter; import java.io.PrintWriter; import java.io.StringWriter; import java.io.UnsupportedEncodingException; import java.io.Writer; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.xml.serialize.OutputFormat; import org.apache.xml.serialize.XMLSerializer; import org.jdom2.Document; import org.jdom2.Element; import org.jdom2.JDOMException; import org.jdom2.input.SAXBuilder; import org.jdom2.output.Format; import org.jdom2.output.SAXOutputter; import org.jdom2.output.XMLOutputter; import org.xml.sax.ContentHandler; import org.xml.sax.SAXException; import edu.unc.lib.dl.xml.StandaloneDatastreamOutputFilter; public class ClientUtils { private static final Log log = LogFactory.getLog(ClientUtils.class); public static Document parseXML(byte[] input) throws SAXException { Document result = null; SAXBuilder builder = new SAXBuilder(); try { result = builder.build(new ByteArrayInputStream(input)); } catch (JDOMException e) { throw new ServiceException("Unexpected error", e); } catch (IOException e) { throw new ServiceException("Unexpected error", e); } return result; } /** * Serializes the FOXML 1.1 JDOM document to a UTF-8 byte array. This method is responsible for assuring that the * FOXML output contains "standalone" datastreams with locally declared namespaces as required by Fedora ingest. * * @param doc * a FOXML 1.1 JDOM document * @return a byte array serialization of the Document */ public static byte[] serializeXML(Document doc) { ByteArrayOutputStream baos = new ByteArrayOutputStream(); Writer pw; try { pw = new OutputStreamWriter(baos, "UTF-8"); } catch (UnsupportedEncodingException e) { throw new ServiceException("UTF-8 character encoding support is required", e); } try { // Filtering SAX Events before serializing. // This ensures that any XML datastreams have locally // declared namespaces, which is a Fedora ingest // requirement. OutputFormat format = new OutputFormat("XML", "UTF-8", true); format.setIndent(2); format.setIndenting(true); format.setPreserveSpace(false); format.setLineWidth(200); XMLSerializer serializer = new XMLSerializer(pw, format); ContentHandler chs = serializer.asContentHandler(); StandaloneDatastreamOutputFilter filter = new StandaloneDatastreamOutputFilter(); filter.setContentHandler(chs); SAXOutputter sax = new SAXOutputter(); sax.setContentHandler(filter); sax.output(doc); pw.flush(); } catch (JDOMException e) { throw new ServiceException("Could not generate SAX events from JDOM.", e); } catch (IOException e) { throw new ServiceException("Could not obtain a content handler for the appropriate format and writer.", e); } byte[] result = baos.toByteArray(); if (log.isDebugEnabled()) { try (StringWriter sw = new StringWriter(); ByteArrayInputStream is = new ByteArrayInputStream(result);) { for (int f = is.read(); f != -1; f = is.read()) { sw.write(f); } log.debug(sw.toString()); } catch (IOException e) { throw new ServiceException(e); } } return result; } /** * Serializes a non-FOXML root XML element. Does not attempt to attach local namespaces to sub-elements. * @param element * @return */ public static byte[] serializeXML(Element element) { Format format = Format.getPrettyFormat(); XMLOutputter outputter = new XMLOutputter(format); try (ByteArrayOutputStream baos = new ByteArrayOutputStream(); Writer pw = new OutputStreamWriter(baos, "UTF-8");) { outputter.output(element, pw); pw.flush(); byte[] result = baos.toByteArray(); return result; } catch (UnsupportedEncodingException e) { throw new ServiceException("UTF-8 character encoding support is required", e); } catch (IOException e) { log.error("Failed to serialize element", e); } return null; } /** * Serializes a JDOM element to a UTF-8 encoded file. Does not enforce locally declared namespaces. * @param element a detached, standalone element * @return */ public static File writeXMLToTempFile(Element element) throws IOException { Format format = Format.getPrettyFormat(); XMLOutputter outputter = new XMLOutputter(format); File result = File.createTempFile("ClientUtils-", ".xml"); try (BufferedWriter writer = new BufferedWriter(new FileWriter(result))) { outputter.output(element, writer); return result; } } /** * Serializes the FOXML 1.1 JDOM document to a UTF-8 byte array. This method is responsible for assuring that the * FOXML output contains "standalone" datastreams with locally declared namespaces as required by Fedora ingest. * * @param doc * a FOXML 1.1 JDOM document * @return a byte array serialization of the Document */ public static File writeXMLToTempFile(Document doc) { File result; try { result = File.createTempFile("ClientUtils-", ".xml"); } catch (IOException e1) { throw new ServiceException("Could not create temp file.", e1); } try (FileOutputStream baos = new FileOutputStream(result); PrintWriter pw = new PrintWriter(baos);) { // Filtering SAX Events before serializing. // This ensures that any XML datastreams have locally // declared namespaces, which is a Fedora ingest // requirement. OutputFormat format = new OutputFormat("XML", "UTF-8", true); format.setIndent(2); format.setIndenting(true); format.setPreserveSpace(false); format.setLineWidth(200); XMLSerializer serializer = new XMLSerializer(pw, format); ContentHandler chs = serializer.asContentHandler(); StandaloneDatastreamOutputFilter filter = new StandaloneDatastreamOutputFilter(); filter.setContentHandler(chs); SAXOutputter sax = new SAXOutputter(); sax.setContentHandler(filter); sax.output(doc); return result; } catch (JDOMException e) { throw new ServiceException("Could not generate SAX events from JDOM.", e); } catch (IOException e) { throw new ServiceException("Could not obtain a content handler for the appropriate format and writer.", e); } } }