Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
  /*
   * Copyright 2006-2007 the original author or authors.
   *
   * 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 org.springframework.batch.item.xml;
 
 import java.io.File;
 import java.io.Writer;
 import java.util.List;
 import java.util.Map;
 
 
An implementation of org.springframework.batch.item.ItemWriter which uses StAX and org.springframework.oxm.Marshaller for serializing object to XML. This item writer also provides restart, statistics and transaction features by implementing corresponding interfaces. The implementation is *not* thread-safe.

Author(s):
Peter Zozom
Robert Kasanicky
 
 public class StaxEventItemWriter<T> extends ExecutionContextUserSupport implements
 
 	private static final Log log = LogFactory.getLog(StaxEventItemWriter.class);
 
 	// default encoding
 	private static final String DEFAULT_ENCODING = "UTF-8";
 
 	// default encoding
 	private static final String DEFAULT_XML_VERSION = "1.0";
 
 	// default root tag name
 	private static final String DEFAULT_ROOT_TAG_NAME = "root";
 
 	// restart data property name
 	private static final String RESTART_DATA_NAME = "position";
 
 	// restart data property name
 	private static final String WRITE_STATISTICS_NAME = "record.count";
 
 	// file system resource
 	private Resource resource;
 
 	// xml marshaller
 	private Marshaller marshaller;
 
 	// encoding to be used while reading from the resource
 
 	// XML version
	// name of the root tag
	// namespace prefix of the root tag
	// namespace of the root tag
	private String rootTagNamespace = "";
	// root element attributes
	private Map<StringStringrootElementAttributes = null;
	// TRUE means, that output file will be overwritten if exists - default is
	// TRUE
	private boolean overwriteOutput = true;
	// file channel
	// wrapper for XML event writer that swallows StartDocument and EndDocument
	// events
	// XML event writer
	// current count of processed records
	private long currentRecordCount = 0;
	private boolean saveState = true;
	private boolean transactional = true;
	}

Set output file.

Parameters:
resource the output file
	public void setResource(Resource resource) {
		this. = resource;
	}

Set Object to XML marshaller.

Parameters:
marshaller the Object to XML marshaller
	public void setMarshaller(Marshaller marshaller) {
		this. = marshaller;
	}

headerCallback is called before writing any items.
	public void setHeaderCallback(StaxWriterCallback headerCallback) {
		this. = headerCallback;
	}

footerCallback is called after writing all items but before closing the file
	public void setFooterCallback(StaxWriterCallback footerCallback) {
		this. = footerCallback;
	}

Flag to indicate that writes should be deferred to the end of a transaction if present. Defaults to true.

Parameters:
transactional the flag to set
	public void setTransactional(boolean transactional) {
		this. = transactional;
	}

Get used encoding.

Returns:
the encoding used
	public String getEncoding() {
		return ;
	}

Set encoding to be used for output file.

Parameters:
encoding the encoding to be used
	public void setEncoding(String encoding) {
		this. = encoding;
	}

Get XML version.

Returns:
the XML version used
	public String getVersion() {
		return ;
	}

Set XML version to be used for output XML.

Parameters:
version the XML version to be used
	public void setVersion(String version) {
		this. = version;
	}

Get the tag name of the root element.

Returns:
the root element tag name
	public String getRootTagName() {
		return ;
	}

Set the tag name of the root element. If not set, default name is used ("root"). Namespace URI and prefix can also be set optionally using the notation:
 {uri}prefix:root
 
The prefix is optional (defaults to empty), but if it is specified then the uri must be provided. In addition you might want to declare other namespaces using the root attributes.

Parameters:
rootTagName the tag name to be used for the root element
	public void setRootTagName(String rootTagName) {
		this. = rootTagName;
	}

Get the namespace prefix of the root element. Empty by default.

Returns:
the rootTagNamespacePrefix
	}

Get the namespace of the root element.

Returns:
the rootTagNamespace
	}

Get attributes of the root element.

Returns:
attributes of the root element
	}

Set the root element attributes to be written. If any of the key names begin with "xmlns:" then they are treated as namespace declarations.

Parameters:
rootElementAttributes attributes of the root element
	public void setRootElementAttributes(Map<StringStringrootElementAttributes) {
		this. = rootElementAttributes;
	}

Set "overwrite" flag for the output file. Flag is ignored when output file processing is restarted.

Parameters:
overwriteOutput
	public void setOverwriteOutput(boolean overwriteOutput) {
		this. = overwriteOutput;
	}
	public void setSaveState(boolean saveState) {
		this. = saveState;
	}

	public void afterPropertiesSet() throws Exception {
		if (.contains("{")) {
			 = .replaceAll("\\{(.*)\\}.*""$1");
			 = .replaceAll("\\{.*\\}(.*)""$1");
			if (.contains(":")) {
				 = .replaceAll(".*:(.*)""$1");
			}
		}
	}

	public void open(ExecutionContext executionContext) {
		Assert.notNull("The resource must be set");
		long startAtPosition = 0;
		boolean restarted = false;
		// if restart data is provided, restart from provided offset
		// otherwise start from beginning
		if (executionContext.containsKey(getKey())) {
			startAtPosition = executionContext.getLong(getKey());
			restarted = true;
		}
		open(startAtPositionrestarted);
		if (startAtPosition == 0) {
			try {
				if ( != null) {
				}
			}
			catch (IOException e) {
				throw new ItemStreamException("Failed to write headerItems"e);
			}
		}
	}

Helper method for opening output source at given file position
	private void open(long positionboolean restarted) {
		File file;
		FileOutputStream os = null;
		try {
			file = .getFile();
			FileUtils.setUpOutputFile(filerestarted);
			Assert.state(.exists(), "Output resource must exist");
			os = new FileOutputStream(filetrue);
			setPosition(position);
		}
		catch (IOException ioe) {
			throw new DataAccessResourceFailureException("Unable to write to file resource: [" +  + "]"ioe);
		}
		XMLOutputFactory outputFactory = XMLOutputFactory.newInstance();
		if (outputFactory.isPropertySupported("com.ctc.wstx.automaticEndElements")) {
			// If the current XMLOutputFactory implementation is supplied by
			// Woodstox >= 3.2.9 we want to disable its
			// automatic end element feature (see:
			// http://jira.codehaus.org/browse/WSTX-165) per
			// http://jira.springframework.org/browse/BATCH-761.
			outputFactory.setProperty("com.ctc.wstx.automaticEndElements".);
		}
		try {
						new Runnable() {
							public void run() {
							}
						});
			}
			else {
			}
			if (!restarted) {
			}
		}
		catch (XMLStreamException xse) {
			throw new DataAccessResourceFailureException("Unable to write to file resource: [" +  + "]"xse);
		}
			throw new DataAccessResourceFailureException("Unable to write to file resource: [" + 
"] with encoding=[" +  + "]"e);
		}
	}

Writes simple XML header containing:
  • xml declaration - defines encoding and XML version
  • opening tag of the root element and its attributes
If this is not sufficient for you, simply override this method. Encoding, version and root tag name can be retrieved with corresponding getters.

Parameters:
writer XML event writer
Throws:
javax.xml.stream.XMLStreamException
	protected void startDocument(XMLEventWriter writerthrows XMLStreamException {
		XMLEventFactory factory = XMLEventFactory.newInstance();
		// write start document
		// write root tag
		if (StringUtils.hasText(getRootTagNamespace())) {
			if (StringUtils.hasText(getRootTagNamespacePrefix())) {
			}
			else {
			}
		}
		// write root tag attributes
		if (!CollectionUtils.isEmpty(getRootElementAttributes())) {
				String key = entry.getKey();
				if (key.startsWith("xmlns")) {
					String prefix = "";
					if (key.contains(":")) {
						prefix = key.substring(key.indexOf(":") + 1);
					}
					writer.add(factory.createNamespace(prefixentry.getValue()));
				}
				else {
					writer.add(factory.createAttribute(keyentry.getValue()));
				}
			}
		}
		/*
		 * This forces the flush to write the end of the root element and avoids
		 * an off-by-one error on restart.
		 */
		writer.add(factory.createIgnorableSpace(""));
		writer.flush();
	}

Writes the EndDocument tag manually.

Parameters:
writer XML event writer
Throws:
javax.xml.stream.XMLStreamException
	protected void endDocument(XMLEventWriter writerthrows XMLStreamException {
		// writer.writeEndDocument(); <- this doesn't work after restart
		// we need to write end tag of the root element manually
		String nsPrefix = !StringUtils.hasText(getRootTagNamespacePrefix()) ? "" : getRootTagNamespacePrefix() + ":";
		try {
			.write("</" + nsPrefix + getRootTagName() + ">");
		}
		catch (IOException ioe) {
			throw new DataAccessResourceFailureException("Unable to close file resource: [" +  + "]"ioe);
		}
	}

Flush and close the output source.

	public void close() {
		// harmless event to close the root tag if there were no items
		XMLEventFactory factory = XMLEventFactory.newInstance();
		try {
		}
		catch (XMLStreamException e) {
		}
		try {
			if ( != null) {
			}
		}
		catch (IOException e) {
			throw new ItemStreamException("Failed to write footer items"e);
		}
		catch (XMLStreamException e) {
			throw new ItemStreamException("Failed to write end document tag"e);
		}
		finally {
			try {
			}
			catch (XMLStreamException e) {
				.error("Unable to close file resource: [" +  + "] " + e);
			}
			finally {
				try {
				}
				catch (IOException e) {
					.error("Unable to close file resource: [" +  + "] " + e);
				}
				finally {
					if (!) {
					}
				}
			}
		}
	}
	private void closeStream() {
		try {
		}
		catch (IOException ioe) {
			.error("Unable to close file resource: [" +  + "] " + ioe);
		}
	}

Write the value objects and flush them to the file.

Parameters:
items the value object
Throws:
java.io.IOException
org.springframework.oxm.XmlMappingException
	public void write(List<? extends T> itemsthrows XmlMappingExceptionIOException {
		for (Object object : items) {
					"Marshaller must support the class of the marshalled object");
		}
		try {
		}
		catch (XMLStreamException e) {
			throw new WriteFailedException("Failed to flush the events"e);
		}
	}

	public void update(ExecutionContext executionContext) {
		if () {
			Assert.notNull(executionContext"ExecutionContext must not be null");
		}
	}
	/*
	 * Get the actual position in file channel. This method flushes any buffered
	 * data before position is read.
	 * 
	 * @return byte offset in file channel
	 */
	private long getPosition() {
		long position;
		try {
			position = .position();
			}
		}
		catch (Exception e) {
			throw new DataAccessResourceFailureException("Unable to write to file resource: [" +  + "]"e);
		}
		return position;
	}

Set the file channel position.

Parameters:
newPosition new file channel position
	private void setPosition(long newPosition) {
		try {
			.truncate(newPosition);
			.position(newPosition);
		}
		catch (IOException e) {
			throw new DataAccessResourceFailureException("Unable to write to file resource: [" +  + "]"e);
		}
	}
New to GrepCode? Check out our FAQ X