OPEN - issue BATCH-113: Mouldy xml class names still in infrastructure
http://opensource.atlassian.com/projects/spring/browse/BATCH-113
This commit is contained in:
@@ -1,61 +0,0 @@
|
||||
/*
|
||||
* 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.io.xml;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import org.springframework.batch.io.xml.xstream.XStreamFactory;
|
||||
|
||||
/**
|
||||
* The <code>ObjectInput</code> interface provides method for reading objects
|
||||
* from input stream and also provides methods for manipulating input stream.
|
||||
* @author peter.zozom
|
||||
* @see XStreamFactory.ObjectInputWrapper
|
||||
*/
|
||||
public interface ObjectInput {
|
||||
|
||||
/**
|
||||
* Enables input stream postprocess after reading from the stream has been
|
||||
* restarted.
|
||||
* @param data
|
||||
*/
|
||||
public void afterRestart(Object data);
|
||||
|
||||
/**
|
||||
* Read and return an object. The class that implements this interface
|
||||
* defines where the object is "read" from.
|
||||
*
|
||||
* @return the object read from the stream
|
||||
* @exception java.lang.ClassNotFoundException If the class of a serialized
|
||||
* object cannot be found.
|
||||
* @exception IOException If any of the usual Input/Output related
|
||||
* exceptions occur.
|
||||
*/
|
||||
public Object readObject() throws ClassNotFoundException, IOException;
|
||||
|
||||
/**
|
||||
* Closes the input stream. Must be called to release any resources
|
||||
* associated with the stream.
|
||||
*/
|
||||
public void close();
|
||||
|
||||
/**
|
||||
* Get actual position in the input stream.
|
||||
* @return actual position in the input stream
|
||||
*/
|
||||
public long position();
|
||||
}
|
||||
@@ -1,33 +0,0 @@
|
||||
/*
|
||||
* 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.io.xml;
|
||||
|
||||
import org.springframework.core.io.Resource;
|
||||
|
||||
/**
|
||||
* ObjectInputFactory creates instance of <code>ObjectInput</code>.
|
||||
* Implementation should be thread-safe.
|
||||
* @author peter.zozom
|
||||
*/
|
||||
public interface ObjectInputFactory {
|
||||
|
||||
/**
|
||||
* Creates instance of {@link ObjectInput}
|
||||
* @return ObjectInput
|
||||
*/
|
||||
public ObjectInput createObjectInput(Resource resource, String encoding);
|
||||
}
|
||||
@@ -1,84 +0,0 @@
|
||||
/*
|
||||
* 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.io.xml;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import org.springframework.batch.io.xml.xstream.XStreamFactory;
|
||||
|
||||
/**
|
||||
* The <code>ObjectOutput</code> interface provides methods for writing
|
||||
* objects to output stream and also provides methods for manipulating output
|
||||
* stream (such as flush, position, truncate, etc.).
|
||||
* @author peter.zozom
|
||||
* @see XStreamFactory.ObjectOutputWrapper
|
||||
*/
|
||||
public interface ObjectOutput {
|
||||
|
||||
/**
|
||||
* Enables output stream postprocess after writing to the stream has been
|
||||
* restarted.
|
||||
* @param data
|
||||
*/
|
||||
public void afterRestart(Object data);
|
||||
|
||||
/**
|
||||
* Write an object to the stream. The class that implements this interface
|
||||
* defines how the object is written.
|
||||
*
|
||||
* @param obj the object to be written
|
||||
* @exception IOException Any of the usual Input/Output related exceptions.
|
||||
*/
|
||||
public void writeObject(Object obj) throws IOException;
|
||||
|
||||
/**
|
||||
* Closes the stream. This method must be called to release any resources
|
||||
* associated with the stream.
|
||||
*/
|
||||
public void close();
|
||||
|
||||
/**
|
||||
* Flushes the stream. This will write any buffered output bytes.
|
||||
*/
|
||||
public void flush();
|
||||
|
||||
/**
|
||||
* Get actual position in the output stream.
|
||||
* @return actual position in the output stream
|
||||
*/
|
||||
public long position();
|
||||
|
||||
/**
|
||||
* Set a new position in the output stream.
|
||||
* @param newPosition the new position, a non-negative integer counting the
|
||||
* number of bytes from the beginning of the file
|
||||
*/
|
||||
public void position(long newPosition);
|
||||
|
||||
/**
|
||||
* Truncates the otput file to the given size.
|
||||
* @param size the new size, a non-negative byte count
|
||||
*/
|
||||
public void truncate(long size);
|
||||
|
||||
/**
|
||||
* Returns the current size of the output file
|
||||
* @return The current size of the output file, measured in bytes
|
||||
*/
|
||||
public long size();
|
||||
|
||||
}
|
||||
@@ -1,33 +0,0 @@
|
||||
/*
|
||||
* 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.io.xml;
|
||||
|
||||
import org.springframework.core.io.Resource;
|
||||
|
||||
/**
|
||||
* ObjectOutputFactory creates instance of <code>ObjectOutput</code>.
|
||||
* Implementation should be thread-safe.
|
||||
* @author peter.zozom
|
||||
*/
|
||||
public interface ObjectOutputFactory {
|
||||
|
||||
/**
|
||||
* Creates instance of {@link ObjectOutput}
|
||||
* @return
|
||||
*/
|
||||
public ObjectOutput createObjectOutput(Resource resource, String encoding);
|
||||
}
|
||||
@@ -1,198 +0,0 @@
|
||||
package org.springframework.batch.io.xml;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.Reader;
|
||||
import java.io.StringReader;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.channels.FileChannel;
|
||||
import java.nio.charset.Charset;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import javax.xml.stream.XMLInputFactory;
|
||||
import javax.xml.stream.XMLStreamException;
|
||||
import javax.xml.transform.Source;
|
||||
import javax.xml.transform.sax.SAXSource;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import org.springframework.dao.DataAccessResourceFailureException;
|
||||
import org.springframework.oxm.Unmarshaller;
|
||||
import org.springframework.oxm.XmlMappingException;
|
||||
import org.springframework.xml.transform.StaxSource;
|
||||
|
||||
import org.xml.sax.SAXException;
|
||||
import org.xml.sax.XMLReader;
|
||||
import org.xml.sax.helpers.XMLReaderFactory;
|
||||
|
||||
/**
|
||||
* Unmarshaller adapter allows to use {@link org.springframework.oxm.Unmarshaller} for
|
||||
* iterative XML record processing.
|
||||
*
|
||||
* {@link org.springframework.oxm.Unmarshaller} always processes whole XML
|
||||
* input at once, but we need to process only one record per one module
|
||||
* iteration (or per one call of the read() method).
|
||||
*
|
||||
* Solution is to cut XML in smaller pieces (each piece contains single record) and call
|
||||
* the unmarshaller to process only this single piece (record).
|
||||
*
|
||||
*/
|
||||
class UnmarshallerAdapter {
|
||||
|
||||
private static final Log log = LogFactory.getLog(UnmarshallerAdapter.class);
|
||||
|
||||
private FileChannel fc;
|
||||
|
||||
private String encoding;
|
||||
|
||||
//original unmarshaller - processes only pieces of XML passed from wrapper
|
||||
private Unmarshaller u;
|
||||
|
||||
//regex matcher - used to cut XML piece holding one record
|
||||
private final Matcher matcher;
|
||||
|
||||
private SourceFactory factory;
|
||||
|
||||
/* ***** Constructor ***** */
|
||||
|
||||
/**
|
||||
* @param originalUnmarshaller unmarshaller to be wrapped
|
||||
*/
|
||||
public UnmarshallerAdapter(Unmarshaller originalUnmarshaller, String recordElementName, FileChannel fc,
|
||||
String encoding, boolean useSaxParser) {
|
||||
this.u = originalUnmarshaller;
|
||||
this.fc = fc;
|
||||
this.encoding = encoding;
|
||||
this.matcher = getMatcher(recordElementName);
|
||||
this.factory = getSourceFactory(useSaxParser);
|
||||
}
|
||||
|
||||
/**
|
||||
* Unmarshal next record.
|
||||
* @see org.springframework.oxm.Unmarshaller#unmarshal(javax.xml.transform.Source)
|
||||
*/
|
||||
public Object unmarshal() throws XmlMappingException, IOException {
|
||||
|
||||
Object result = null;
|
||||
|
||||
String record = readNextRecord();
|
||||
if (record != null) {
|
||||
result = u.unmarshal(factory.getSource(record));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Read next piece of XML.
|
||||
* @return xml string holding one record
|
||||
*/
|
||||
private String readNextRecord() {
|
||||
|
||||
String result = null;
|
||||
|
||||
if (matcher.find()) {
|
||||
result = matcher.group();
|
||||
}
|
||||
if (result != null) {
|
||||
try {
|
||||
fc.position(matcher.end());
|
||||
} catch (IOException e) {
|
||||
throw new IllegalStateException("Error while adjusting filechannel position");
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/* ***** Private helper methods ***** */
|
||||
|
||||
/**
|
||||
* Get regex matcher, which cuts XML to pieces
|
||||
* @param elemName name of the element that represents one record
|
||||
* @return the matcher
|
||||
*/
|
||||
private Matcher getMatcher(String elemName) {
|
||||
|
||||
CharSequence cs = null;
|
||||
|
||||
try {
|
||||
// Create a read-only CharBuffer on the file
|
||||
ByteBuffer bbuf = fc.map(FileChannel.MapMode.READ_ONLY, fc.position(), fc.size() - fc.position());
|
||||
cs = Charset.forName(encoding).newDecoder().decode(bbuf);
|
||||
}
|
||||
catch (IOException ioe) {
|
||||
log.error(ioe);
|
||||
throw new DataAccessResourceFailureException("Unable to get input stream", ioe);
|
||||
}
|
||||
|
||||
String prefix = (elemName.indexOf(':') < 0) ? "(?:[^:]*?:)?" : "";
|
||||
String re = "<" + prefix + elemName + "[^/>]*?/>|<" + prefix + elemName + "[\\s>][\\S\\s]*?</" + prefix
|
||||
+ elemName + ">";
|
||||
|
||||
return Pattern.compile(re, Pattern.MULTILINE).matcher(cs);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get SourceFactory which will create SAX or StAX source (based on useSaxParser flag)
|
||||
* @param useSaxParser
|
||||
*/
|
||||
private SourceFactory getSourceFactory(boolean useSaxParser) {
|
||||
|
||||
SourceFactory sf;
|
||||
|
||||
if (useSaxParser) {
|
||||
sf = new SourceFactory() {
|
||||
public Source getSource(String xml) {
|
||||
|
||||
Source source = null;
|
||||
|
||||
Reader r = new StringReader(xml);
|
||||
try {
|
||||
XMLReader reader;
|
||||
try {
|
||||
reader = XMLReaderFactory.createXMLReader();
|
||||
}
|
||||
catch (SAXException se) {
|
||||
reader = XMLReaderFactory.createXMLReader("org.apache.crimson.parser.XMLReaderImpl");
|
||||
}
|
||||
source = new SAXSource(reader, new org.xml.sax.InputSource(r));
|
||||
}
|
||||
catch (SAXException se) {
|
||||
log.error(se);
|
||||
throw new DataAccessResourceFailureException("Unable to get XML reader", se);
|
||||
}
|
||||
|
||||
return source;
|
||||
}
|
||||
};
|
||||
}
|
||||
else {
|
||||
sf = new SourceFactory() {
|
||||
public Source getSource(String xml) {
|
||||
XMLInputFactory xsf = XMLInputFactory.newInstance();
|
||||
|
||||
Source source = null;
|
||||
|
||||
try {
|
||||
Reader r = new StringReader(xml);
|
||||
source = new StaxSource(xsf.createXMLStreamReader(r));
|
||||
}
|
||||
catch (XMLStreamException xse) {
|
||||
log.error(xse);
|
||||
throw new DataAccessResourceFailureException("Unable to get XML reader", xse);
|
||||
}
|
||||
return source;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
return sf;
|
||||
}
|
||||
|
||||
private interface SourceFactory {
|
||||
public Source getSource(String xml);
|
||||
}
|
||||
}
|
||||
@@ -1,79 +0,0 @@
|
||||
/*
|
||||
* 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.io.xml;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.xml.sax.SAXException;
|
||||
import org.xml.sax.SAXParseException;
|
||||
import org.xml.sax.helpers.DefaultHandler;
|
||||
|
||||
/**
|
||||
* SAX error handler implementation. This implementation only logs warnings and
|
||||
* errors and re-throws exceptions.
|
||||
*
|
||||
* @author peter.zozom
|
||||
*/
|
||||
public class XmlErrorHandler extends DefaultHandler {
|
||||
private static final Log log = LogFactory.getLog(XmlErrorHandler.class);
|
||||
|
||||
/**
|
||||
* @param e parsing exception
|
||||
* @throws SAXException re-thrown exception
|
||||
* @see org.xml.sax.helpers.DefaultHandler#warning(org.xml.sax.SAXParseException)
|
||||
*/
|
||||
public void warning(SAXParseException e) throws SAXException {
|
||||
log.debug("Warning: \n" + printInfo(e));
|
||||
throw new SAXException(e);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param e parsing exception
|
||||
* @throws SAXException re-thrown exception
|
||||
* @see org.xml.sax.helpers.DefaultHandler#error(org.xml.sax.SAXParseException)
|
||||
*/
|
||||
public void error(SAXParseException e) throws SAXException {
|
||||
log.debug("Warning: \n" + printInfo(e));
|
||||
throw new SAXException(e);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param e parsing exception
|
||||
* @throws SAXException re-thrown exception
|
||||
* @see org.xml.sax.helpers.DefaultHandler#fatalError(org.xml.sax.SAXParseException)
|
||||
*/
|
||||
public void fatalError(SAXParseException e) throws SAXException {
|
||||
log.debug("Warning: \n" + printInfo(e));
|
||||
throw new SAXException(e);
|
||||
}
|
||||
|
||||
private String printInfo(SAXParseException e) {
|
||||
StringBuffer sb = new StringBuffer();
|
||||
sb.append(" Public ID: \n");
|
||||
sb.append(e.getPublicId());
|
||||
sb.append(" System ID: \n");
|
||||
sb.append(e.getSystemId());
|
||||
sb.append(" Line number: \n");
|
||||
sb.append(e.getLineNumber());
|
||||
sb.append(" Column number: \n");
|
||||
sb.append(e.getColumnNumber());
|
||||
sb.append(" Message: \n");
|
||||
sb.append(e.getMessage());
|
||||
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
||||
@@ -1,489 +0,0 @@
|
||||
/*
|
||||
* 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.io.xml;
|
||||
|
||||
import java.io.EOFException;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Properties;
|
||||
|
||||
import javax.xml.parsers.FactoryConfigurationError;
|
||||
import javax.xml.parsers.ParserConfigurationException;
|
||||
import javax.xml.parsers.SAXParser;
|
||||
import javax.xml.parsers.SAXParserFactory;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.batch.io.InputSource;
|
||||
import org.springframework.batch.io.Skippable;
|
||||
import org.springframework.batch.io.exception.BatchCriticalException;
|
||||
import org.springframework.batch.io.exception.BatchEnvironmentException;
|
||||
import org.springframework.batch.repeat.synch.BatchTransactionSynchronizationManager;
|
||||
import org.springframework.batch.restart.GenericRestartData;
|
||||
import org.springframework.batch.restart.RestartData;
|
||||
import org.springframework.batch.restart.Restartable;
|
||||
import org.springframework.batch.statistics.StatisticsProvider;
|
||||
import org.springframework.beans.factory.DisposableBean;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.transaction.support.TransactionSynchronization;
|
||||
import org.springframework.util.Assert;
|
||||
import org.xml.sax.SAXException;
|
||||
import org.xml.sax.helpers.DefaultHandler;
|
||||
|
||||
/**
|
||||
* XmlInputTemplate is implementation of {@link InputSource} which
|
||||
* processes XML input independently of technologies used for parsing XML files
|
||||
* and mapping XML to value objects. It has references only to interfaces, not
|
||||
* concrete implementations. It uses {@link ObjectInputFactory} interface for
|
||||
* getting {@link ObjectInput}, which is interface for retrieving value objects
|
||||
* from the input stream. So it's easy to plug-in any technology for parsing XML
|
||||
* and mapping it to value object by implementing these interfaces. See
|
||||
* implementation of {@link ObjectInputFactory} interface, which uses StAX
|
||||
* as XML parser and XStream as XML-to-ValueObjects mapper.
|
||||
* <p>
|
||||
* Current implementation also allows validation of XML file against XSD schema.
|
||||
* This validation is realized by using SAXParser. Validation of the whole XML
|
||||
* file is performed in the {@link #open()} method, because SAXParser does not
|
||||
* allow to process only part of the XML, then stop and continue later with
|
||||
* processing. This type of processing can be realized by using any pull-parser
|
||||
* (e.g. StAX), but StAX API does not provide methods for validation. So be
|
||||
* careful when using this validation, because it means to parse XML twice: once
|
||||
* to validate and once to read and map. Validation can be turned on/off by
|
||||
* {@link #setValidating(boolean)} method. By default is validation turned off.<br/>
|
||||
* This validation should be refactored in future. Validation should be provided
|
||||
* either by {@link ObjectInput} or some new interface.
|
||||
* <p>
|
||||
* This input template also provides restart, skip, statistics and transaction
|
||||
* features by implementing corresponding interfaces.
|
||||
*
|
||||
* @author peter.zozom
|
||||
* @see ObjectInput
|
||||
* @see ObjectInputFactory
|
||||
*/
|
||||
public class XmlInputSource implements InputSource, Skippable, Restartable,
|
||||
TransactionSynchronization, StatisticsProvider, InitializingBean, DisposableBean {
|
||||
|
||||
private static final Log log = LogFactory.getLog(XmlInputSource.class);
|
||||
|
||||
private static final String DEFAULT_ENCODING = "UTF-8";
|
||||
|
||||
/*
|
||||
* Unique source name used to construct this xml reader input source -
|
||||
* specified by the configuration file.
|
||||
*/
|
||||
private String sourceName = null;
|
||||
|
||||
private Resource resource;
|
||||
|
||||
private ObjectInputFactory inputFactory;
|
||||
|
||||
private boolean validating = false;
|
||||
|
||||
private String encoding = DEFAULT_ENCODING;
|
||||
|
||||
private Properties statistics = new Properties();
|
||||
|
||||
public static final String READ_STATISTICS_NAME = "Read";
|
||||
|
||||
public static final String RESTART_DATA_NAME = "xmlinputtemplate.currentRecordCount";
|
||||
|
||||
private InputState state = new InputState();
|
||||
|
||||
// accessor method for the threadlocal state object
|
||||
private InputState getState() {
|
||||
return (InputState) state;
|
||||
}
|
||||
|
||||
public void afterPropertiesSet() throws Exception {
|
||||
Assert.notNull(resource);
|
||||
Assert.state(resource.exists(), "Input resource does not exist: ["+resource+"]");
|
||||
}
|
||||
|
||||
/**
|
||||
* Setter for input resource.
|
||||
*
|
||||
* @param resource
|
||||
*/
|
||||
public void setResource(Resource resource) {
|
||||
this.resource = resource;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return current status of the validation flag
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public boolean isValidating() {
|
||||
return validating;
|
||||
}
|
||||
|
||||
/**
|
||||
* Turn validation on/off for the input source
|
||||
*
|
||||
* @param validating
|
||||
*/
|
||||
public void setValidating(boolean validating) {
|
||||
this.validating = validating;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize the input source and validates input XML file if validation is
|
||||
* turned on. This method should be called for each thread using same
|
||||
* XmlInputTemplate instance.
|
||||
*
|
||||
* @see org.springframework.batch.item.ResourceLifecycle#open()
|
||||
*/
|
||||
public void open() {
|
||||
InputState is = getState();
|
||||
if (!is.initialized) {
|
||||
registerSynchronization();
|
||||
initializeObjectInput();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers object for transaction synchronization
|
||||
*/
|
||||
protected void registerSynchronization() {
|
||||
BatchTransactionSynchronizationManager.registerSynchronization(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Close the input source
|
||||
*
|
||||
* @see org.springframework.batch.item.ResourceLifecycle#close()
|
||||
*/
|
||||
public void close() {
|
||||
InputState is = getState();
|
||||
is.objectInput.close();
|
||||
is.initialized = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calls close to ensure that bean factories can close and always release
|
||||
* resources.
|
||||
*
|
||||
* @see org.springframework.beans.factory.DisposableBean#destroy()
|
||||
*/
|
||||
public void destroy() throws Exception {
|
||||
close();
|
||||
}
|
||||
|
||||
/*
|
||||
* Initializes and obtains the ObjectInput from the ObjectInputFactory and
|
||||
* validates input XML file if validation is turned on.
|
||||
*/
|
||||
private void initializeObjectInput() {
|
||||
InputState is = getState();
|
||||
is.initialized = false;
|
||||
|
||||
if (isValidating()) {
|
||||
validateInputFile(resource);
|
||||
}
|
||||
|
||||
is.objectInput = inputFactory.createObjectInput(resource, getEncoding());
|
||||
|
||||
is.lastCommitPoint = is.objectInput.position();
|
||||
is.initialized = true;
|
||||
}
|
||||
|
||||
/*
|
||||
* Validates input xml file against XSD schema.
|
||||
*
|
||||
* @param file File to be validated
|
||||
*/
|
||||
private void validateInputFile(Resource resource) {
|
||||
try {
|
||||
SAXParserFactory factory = getSaxFactory();
|
||||
|
||||
factory.setValidating(true);
|
||||
factory.setNamespaceAware(true);
|
||||
factory.setFeature("http://apache.org/xml/features/validation/schema", true);
|
||||
|
||||
SAXParser parser = factory.newSAXParser();
|
||||
DefaultHandler handler = getDefaultHandler();
|
||||
parser.parse(resource.getInputStream(), handler, resource.getURL().toExternalForm());
|
||||
}
|
||||
catch (ParserConfigurationException pce) {
|
||||
log.error(pce);
|
||||
throw new BatchEnvironmentException("Unable to configure parser.", pce);
|
||||
}
|
||||
catch (SAXException se) {
|
||||
log.error(se);
|
||||
throw new BatchEnvironmentException("Error during parsing the input file.", se);
|
||||
}
|
||||
catch (IOException ioe) {
|
||||
log.error(ioe);
|
||||
throw new BatchEnvironmentException("Error reading input file.", ioe);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Get default handler for xml validation
|
||||
*
|
||||
* @return instance of DefaultHandler
|
||||
*/
|
||||
private DefaultHandler getDefaultHandler() {
|
||||
return new XmlErrorHandler();
|
||||
}
|
||||
|
||||
/*
|
||||
* Creates instance of SAXParserFactory
|
||||
*
|
||||
* @return instance of SAXParserFactory @throws FactoryConfigurationError
|
||||
*/
|
||||
protected SAXParserFactory getSaxFactory() throws FactoryConfigurationError {
|
||||
SAXParserFactory factory = SAXParserFactory.newInstance();
|
||||
return factory;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the next record from the input file and map it to a value object.
|
||||
*
|
||||
* @return next record if found or <code>null</code> to signal the end of
|
||||
* the input data.
|
||||
* @see org.springframework.batch.io.InputSource
|
||||
*/
|
||||
public Object read() {
|
||||
InputState is = getState();
|
||||
|
||||
if (!is.initialized) {
|
||||
open();
|
||||
}
|
||||
|
||||
Object result = null;
|
||||
|
||||
do {
|
||||
result = readNextRecord();
|
||||
is.currentRecordCount++;
|
||||
} while (is.skipLines.contains(new Integer(is.currentRecordCount)));
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* Reads next record
|
||||
*
|
||||
* @return next record
|
||||
*/
|
||||
private Object readNextRecord() {
|
||||
InputState is = getState();
|
||||
Object result;
|
||||
|
||||
try {
|
||||
result = is.objectInput.readObject();
|
||||
}
|
||||
catch (EOFException eofe) {
|
||||
log.debug("Parsing of XML finished");
|
||||
result = null;
|
||||
}
|
||||
catch (IOException ioe) {
|
||||
log.error(ioe);
|
||||
throw new BatchCriticalException("Unable to read from ObjectInputStream", ioe);
|
||||
}
|
||||
catch (ClassNotFoundException cnfe) {
|
||||
log.error(cnfe);
|
||||
throw new BatchEnvironmentException("Bad xml mapping", cnfe);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Postprocess after transaction commit/rollback. Called from transaction
|
||||
* manager.
|
||||
*
|
||||
* @param status indicates whether it was a rollback or commit
|
||||
*/
|
||||
public void afterCompletion(int status) {
|
||||
if (status == TransactionSynchronization.STATUS_COMMITTED) {
|
||||
transactionComitted();
|
||||
}
|
||||
else if (status == TransactionSynchronization.STATUS_ROLLED_BACK) {
|
||||
transactionRolledback();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Postprocess after transaction commit
|
||||
*/
|
||||
private void transactionComitted() {
|
||||
InputState is = getState();
|
||||
is.skipLines = new ArrayList();
|
||||
is.lastCommitPoint = is.objectInput.position();
|
||||
}
|
||||
|
||||
/*
|
||||
* Postprocess after transaction rollback
|
||||
*/
|
||||
private void transactionRolledback() {
|
||||
InputState is = getState();
|
||||
is.currentRecordCount = 0;
|
||||
|
||||
// remember list of skipped lines and last commit point
|
||||
List sl = is.skipLines;
|
||||
long cp = is.lastCommitPoint;
|
||||
// XMLStreamReader is forward only, so we need to start from beginnig
|
||||
close();
|
||||
// this will also reset skipLines
|
||||
open();
|
||||
// so after init get new InputState and set skipLines and
|
||||
// lastCommitPoint
|
||||
is = getState();
|
||||
is.skipLines = sl;
|
||||
is.lastCommitPoint = cp;
|
||||
|
||||
long currentLocation = is.objectInput.position();
|
||||
while (currentLocation < is.lastCommitPoint) {
|
||||
readNextRecord();
|
||||
is.currentRecordCount++;
|
||||
currentLocation = is.objectInput.position();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns name of the input source.
|
||||
*
|
||||
* @return input source name
|
||||
*/
|
||||
public String getName() {
|
||||
return sourceName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets name of the input source.
|
||||
*
|
||||
*/
|
||||
public void setName(String newName) {
|
||||
this.sourceName = newName;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns the restart data for the input source. It returns the
|
||||
* current record count which can be used to re-initialze the batch job in
|
||||
* case of restart.
|
||||
*
|
||||
* @see org.springframework.batch.container.Restartable#getRestartData()
|
||||
*/
|
||||
public RestartData getRestartData() {
|
||||
Properties restartData = new Properties();
|
||||
restartData.setProperty(RESTART_DATA_NAME, String.valueOf(getState().currentRecordCount));
|
||||
return new GenericRestartData(restartData);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method initializes the input source for restart. It opens the input
|
||||
* file and position the xml reader according to information provided by the
|
||||
* restart data.
|
||||
*
|
||||
* @param restartData restart data information
|
||||
* @see org.springframework.batch.container.Restartable#initForRestart(java.lang.Object)
|
||||
*/
|
||||
public void restoreFrom(RestartData restartData) {
|
||||
if (restartData == null || restartData.getProperties() == null ||
|
||||
restartData.getProperties().getProperty(RESTART_DATA_NAME) == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
InputState is = getState();
|
||||
int startAtRecord = Integer.parseInt(restartData.getProperties().getProperty(RESTART_DATA_NAME));
|
||||
|
||||
for (int i = 0; i < startAtRecord; i++) {
|
||||
readNextRecord();
|
||||
}
|
||||
|
||||
is.currentRecordCount = startAtRecord;
|
||||
}
|
||||
|
||||
/**
|
||||
* Skip the current record.
|
||||
* @see org.springframework.batch.container.advice.SkipAdvice#skip()
|
||||
*/
|
||||
public void skip() {
|
||||
InputState is = getState();
|
||||
is.skipLines.add(new Integer(is.currentRecordCount));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get encoding.
|
||||
* @return the character encoding of the stream
|
||||
*/
|
||||
public String getEncoding() {
|
||||
return encoding;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set encoding.
|
||||
* @param encoding the character encoding of the stream
|
||||
*/
|
||||
public void setEncoding(String encoding) {
|
||||
this.encoding = encoding;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get statistics for the processed input.
|
||||
* @return actual statistics for the processed input
|
||||
* @see org.springframework.batch.container.advice.StatisticsAdvice#getStatistics()
|
||||
*/
|
||||
public Properties getStatistics() {
|
||||
|
||||
statistics.setProperty(READ_STATISTICS_NAME, String.valueOf(getState().currentRecordCount));
|
||||
return statistics;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the ObjectInputFactory which is used for retrieving ObjectInput
|
||||
* @param inputFactory the factory to use
|
||||
*/
|
||||
public void setInputFactory(ObjectInputFactory inputFactory) {
|
||||
this.inputFactory = inputFactory;
|
||||
}
|
||||
|
||||
/* *** Intentionally unimplemented methods *** */
|
||||
|
||||
public void suspend() {
|
||||
}
|
||||
|
||||
public void resume() {
|
||||
}
|
||||
|
||||
public void beforeCommit(boolean arg0) {
|
||||
}
|
||||
|
||||
public void beforeCompletion() {
|
||||
}
|
||||
|
||||
public void afterCommit() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Value object holding state of the input source.
|
||||
*/
|
||||
private static class InputState {
|
||||
boolean initialized = false;
|
||||
|
||||
int currentRecordCount = 0;
|
||||
|
||||
ObjectInput objectInput;
|
||||
|
||||
List skipLines = new ArrayList();
|
||||
|
||||
long lastCommitPoint;
|
||||
}
|
||||
}
|
||||
@@ -1,397 +0,0 @@
|
||||
package org.springframework.batch.io.xml;
|
||||
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.nio.channels.FileChannel;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Properties;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import org.springframework.batch.io.InputSource;
|
||||
import org.springframework.batch.io.Skippable;
|
||||
import org.springframework.batch.repeat.synch.BatchTransactionSynchronizationManager;
|
||||
import org.springframework.batch.restart.GenericRestartData;
|
||||
import org.springframework.batch.restart.RestartData;
|
||||
import org.springframework.batch.restart.Restartable;
|
||||
import org.springframework.batch.statistics.StatisticsProvider;
|
||||
import org.springframework.beans.factory.DisposableBean;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.core.io.FileSystemResource;
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.dao.DataAccessResourceFailureException;
|
||||
import org.springframework.oxm.Unmarshaller;
|
||||
import org.springframework.transaction.support.TransactionSynchronization;
|
||||
import org.springframework.transaction.support.TransactionSynchronizationAdapter;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* <p>XmlInputSource2 is {@link InputSource} implementation which processes XML input file
|
||||
* and maps XML elements to objects. It uses {@link org.springframework.oxm.Unmarshaller}
|
||||
* for parsing XML and for OXM mapping. This allows to plug-in various OXM frameworks.
|
||||
* Spring-ws' OXM package provides implementations for Castor, JAXB, JiBX,
|
||||
* XmlBeans and XStream.</p>
|
||||
*
|
||||
* <p>{@link org.springframework.oxm.Unmarshaller} always processes whole XML
|
||||
* input at once, but we need to process only one record per one module
|
||||
* iteration. Therefore XmlInputSource2 uses {@link UnmarshallerAdapter} which cuts XML
|
||||
* into smaller pieces (each piece contains a single record) and calls the unmarshaller
|
||||
* to process only this single piece (record).</p>
|
||||
*
|
||||
* <p><b>XmlInputSource2 configuration</b></p>
|
||||
* <p>Mandatory bean properties:
|
||||
* <ul>
|
||||
* <li><i>resource</i> - resource pointing to XML input file. Currently, only
|
||||
* {@link FileSystemResource} is supported.</li>
|
||||
* <li><i>unmarshaller</i> - any implementation of the {@link Unmarshaller}</li>
|
||||
* <li><i>recordElementName</i> - name of the XML element which represents single record</li>
|
||||
* </ul>
|
||||
* </p>
|
||||
* <p>Optional bean properties (if not set, default value is used):
|
||||
* <ul>
|
||||
* <li><i>encoding</i> - input file encoding (default value is UTF-8)</li>
|
||||
* <li><i>useSaxParser</i> - TRUE forces unmarshaller to use SAX parser instead StAX parser.
|
||||
* This can be used for performance optimization. Performance of SAX and StAX can vary
|
||||
* depending on OXM framework used and XML record size. Default value is FALSE</li>
|
||||
* </ul>
|
||||
* </p>
|
||||
*
|
||||
* <p>Limitations:
|
||||
* <ul>
|
||||
* <li>processing of nested records is not supported:</li>
|
||||
* <pre> <folder>
|
||||
* <folder></folder> <- this is not supported
|
||||
* <file></file>
|
||||
* </folder>
|
||||
* <folder>
|
||||
* <file></file>
|
||||
* </folder></pre>
|
||||
* <li>References (idref) in XML are not supported</li>
|
||||
* <li>Validation against XSD schema is not implemented</li>
|
||||
* </ul>
|
||||
* </p>
|
||||
*
|
||||
* @see org.springframework.oxm.Unmarshaller
|
||||
* @see org.springframework.batch.io.xml.UnmarshallerAdapter
|
||||
* @author Peter Zozom
|
||||
*/
|
||||
public class XmlInputSource2 implements InputSource, Skippable, Restartable, StatisticsProvider, InitializingBean,
|
||||
DisposableBean {
|
||||
|
||||
//logger
|
||||
private static final Log log = LogFactory.getLog(XmlInputSource2.class);
|
||||
|
||||
//default encoding
|
||||
private static final String DEFAULT_ENCODING = "UTF-8";
|
||||
|
||||
//restart data property name
|
||||
private static final String RESTART_DATA_NAME = "staxinputsource.position";
|
||||
|
||||
//read statistics property name
|
||||
public static final String READ_STATISTICS_NAME = "Read";
|
||||
|
||||
//file system resource
|
||||
private Resource resource;
|
||||
|
||||
//xml unmarshaller (Castor, JAXB, JiBX, XmlBeans or XStream)
|
||||
private Unmarshaller unmarshaller;
|
||||
|
||||
//unmarshaller adapter
|
||||
private UnmarshallerAdapter unmarshallerAdapter;
|
||||
|
||||
//file channel associated with Resource
|
||||
private FileChannel fc;
|
||||
|
||||
//encoding to be used while reading from the resource
|
||||
private String encoding = DEFAULT_ENCODING;
|
||||
|
||||
//name of the element which represents record
|
||||
private String recordElementName;
|
||||
|
||||
//force to use SAX parser. By default StAX parser is used.
|
||||
private boolean useSaxParser = false;
|
||||
|
||||
//signalizes that input source has been initialized
|
||||
private boolean initialized = false;
|
||||
|
||||
//transaction synchronization object
|
||||
private TransactionSynchronization synchronization = new XmlInputSource2TransactionSychronization();
|
||||
|
||||
//current count of processed records
|
||||
private long currentRecordCount = 0;
|
||||
|
||||
//file channel position at last commit point
|
||||
private long lastCommitPointPosition = 0;
|
||||
|
||||
//count of processed records at last commit point
|
||||
private long lastCommitPointRecordCount = 0;
|
||||
|
||||
//list of skipped record numbers
|
||||
private List skipRecords = new ArrayList();
|
||||
|
||||
//statistics
|
||||
private Properties statistics = new Properties();
|
||||
|
||||
/**
|
||||
* Set the encoding to be used while reading from the Resource
|
||||
* @param encoding the encoding to be used
|
||||
*/
|
||||
public void setEncoding(String encoding) {
|
||||
this.encoding = encoding;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the resource to be read from. Currently is only {@link FileSystemResource} supported.
|
||||
* @param resource the Resource to be read from
|
||||
*/
|
||||
public void setResource(Resource resource) {
|
||||
this.resource = resource;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the {@link Unmarshaller} implementation to be used for Object XML mapping (e.g. JAXB, JiBX, XmlBeans...).
|
||||
* @see org.springframework.oxm.Unmarshaller
|
||||
* @param unmarshaller the OXM unmarshaller
|
||||
*/
|
||||
public void setUnmarshaller(Unmarshaller unmarshaller) {
|
||||
this.unmarshaller = unmarshaller;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the name of the element which represents the record.
|
||||
* @param elementName the element name
|
||||
*/
|
||||
public void setRecordElementName(String elementName) {
|
||||
this.recordElementName = elementName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Force to use SAX parser instead of StAX parser.
|
||||
* @param useSaxParser if true SAX parser will be used, else StAX parser will be used
|
||||
*/
|
||||
public void setUseSaxParser(boolean useSaxParser) {
|
||||
this.useSaxParser = useSaxParser;
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies bean configuration. Resource, Unmarshaller and record element name are mandatory.
|
||||
* @throws Exception
|
||||
* @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet()
|
||||
*/
|
||||
public void afterPropertiesSet() throws Exception {
|
||||
Assert.notNull(resource);
|
||||
Assert.state(resource.exists(), "Input resource does not exist: [" + resource + "]");
|
||||
Assert.notNull(unmarshaller);
|
||||
Assert.hasLength(recordElementName);
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws Exception
|
||||
* @see org.springframework.beans.factory.DisposableBean#destroy()
|
||||
*/
|
||||
public void destroy() throws Exception {
|
||||
close();
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers the input source for transaction synchronization.
|
||||
*/
|
||||
private void registerSynchronization() {
|
||||
BatchTransactionSynchronizationManager.registerSynchronization(synchronization);
|
||||
}
|
||||
|
||||
/**
|
||||
* Opens the input source.
|
||||
* @see org.springframework.batch.item.ResourceLifecycle#open()
|
||||
*/
|
||||
public void open() {
|
||||
|
||||
registerSynchronization();
|
||||
|
||||
try {
|
||||
InputStream is = resource.getInputStream();
|
||||
|
||||
if (is instanceof FileInputStream) {
|
||||
fc = ((FileInputStream) is).getChannel();
|
||||
}
|
||||
else {
|
||||
throw new IllegalArgumentException("Only file input stream is supported");
|
||||
}
|
||||
|
||||
this.unmarshallerAdapter = new UnmarshallerAdapter(unmarshaller, recordElementName, fc, encoding,
|
||||
useSaxParser);
|
||||
|
||||
}
|
||||
catch (IOException ioe) {
|
||||
log.error(ioe);
|
||||
throw new DataAccessResourceFailureException("Unable to get input stream", ioe);
|
||||
}
|
||||
|
||||
initialized = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Closes the input source.
|
||||
* @see org.springframework.batch.item.ResourceLifecycle#close()
|
||||
*/
|
||||
public void close() {
|
||||
|
||||
initialized = false;
|
||||
|
||||
try {
|
||||
fc.close();
|
||||
}
|
||||
catch (IOException ioe) {
|
||||
log.error(ioe);
|
||||
throw new DataAccessResourceFailureException("Unable to close input Source", ioe);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Read object from the input.
|
||||
* @return
|
||||
* @see org.springframework.batch.io.InputSource#read()
|
||||
*/
|
||||
public Object read() {
|
||||
if (!initialized) {
|
||||
open();
|
||||
}
|
||||
|
||||
Object o;
|
||||
|
||||
do {
|
||||
currentRecordCount++;
|
||||
|
||||
try {
|
||||
o = unmarshallerAdapter.unmarshal();
|
||||
}
|
||||
catch (IOException ioe) {
|
||||
log.error(ioe);
|
||||
throw new DataAccessResourceFailureException("Unable to close XML Input Source", ioe);
|
||||
}
|
||||
} while (skipRecords.contains(new Long(currentRecordCount)));
|
||||
|
||||
return o;
|
||||
}
|
||||
|
||||
/**
|
||||
* Mark current record to be skipped.
|
||||
* @see org.springframework.batch.io.Skippable#skip()
|
||||
*/
|
||||
public void skip() {
|
||||
skipRecords.add(new Long(currentRecordCount));
|
||||
}
|
||||
|
||||
/**
|
||||
* @return
|
||||
* @see org.springframework.batch.restart.Restartable#getRestartData()
|
||||
*/
|
||||
public RestartData getRestartData() {
|
||||
Properties restartData = new Properties();
|
||||
|
||||
restartData.setProperty(RESTART_DATA_NAME, String.valueOf(getPosition()));
|
||||
|
||||
return new GenericRestartData(restartData);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get current file position.
|
||||
* @return file position
|
||||
*/
|
||||
private long getPosition() {
|
||||
|
||||
long pos = 0;
|
||||
|
||||
try {
|
||||
pos = fc.position();
|
||||
}
|
||||
catch (IOException ioe) {
|
||||
throw new DataAccessResourceFailureException("Unable to get file position", ioe);
|
||||
}
|
||||
|
||||
return pos;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param data
|
||||
* @see org.springframework.batch.restart.Restartable#restoreFrom(org.springframework.batch.restart.RestartData)
|
||||
*/
|
||||
public void restoreFrom(RestartData data) {
|
||||
if (data == null || data.getProperties() == null || data.getProperties().getProperty(RESTART_DATA_NAME) == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!initialized) {
|
||||
open();
|
||||
}
|
||||
|
||||
long startAtPosition = Long.parseLong(data.getProperties().getProperty(RESTART_DATA_NAME));
|
||||
setPosition(startAtPosition);
|
||||
this.unmarshallerAdapter = new UnmarshallerAdapter(unmarshaller, recordElementName, fc, encoding, useSaxParser);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param startAtPosition
|
||||
*/
|
||||
private void setPosition(long position) {
|
||||
|
||||
try {
|
||||
fc.position(position);
|
||||
}
|
||||
catch (IOException ioe) {
|
||||
throw new DataAccessResourceFailureException("Unable to set file position", ioe);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return
|
||||
* @see org.springframework.batch.statistics.StatisticsProvider#getStatistics()
|
||||
*/
|
||||
public Properties getStatistics() {
|
||||
statistics.setProperty(READ_STATISTICS_NAME, String.valueOf(currentRecordCount));
|
||||
return statistics;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Encapsulates transaction events for the XmlInputSource2.
|
||||
*/
|
||||
private class XmlInputSource2TransactionSychronization extends TransactionSynchronizationAdapter {
|
||||
|
||||
/**
|
||||
* @param status
|
||||
* @see org.springframework.transaction.support.TransactionSynchronizationAdapter#afterCompletion(int)
|
||||
*/
|
||||
public void afterCompletion(int status) {
|
||||
if (status == TransactionSynchronization.STATUS_COMMITTED) {
|
||||
transactionComitted();
|
||||
}
|
||||
else if (status == TransactionSynchronization.STATUS_ROLLED_BACK) {
|
||||
transactionRolledback();
|
||||
}
|
||||
}
|
||||
|
||||
private void transactionComitted() {
|
||||
lastCommitPointPosition = getPosition();
|
||||
lastCommitPointRecordCount = currentRecordCount;
|
||||
skipRecords = new ArrayList();
|
||||
}
|
||||
|
||||
private void transactionRolledback() {
|
||||
currentRecordCount = lastCommitPointRecordCount;
|
||||
setPosition(lastCommitPointPosition);
|
||||
unmarshallerAdapter = new UnmarshallerAdapter(unmarshaller, recordElementName, fc, encoding, useSaxParser);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//package visibility method necessary to simulate transaction events in tests
|
||||
TransactionSynchronization getSynchronization() {
|
||||
return synchronization;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,408 +0,0 @@
|
||||
/*
|
||||
* 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.io.xml;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.Properties;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.batch.io.OutputSource;
|
||||
import org.springframework.batch.io.exception.BatchEnvironmentException;
|
||||
import org.springframework.batch.repeat.synch.BatchTransactionSynchronizationManager;
|
||||
import org.springframework.batch.restart.GenericRestartData;
|
||||
import org.springframework.batch.restart.RestartData;
|
||||
import org.springframework.batch.restart.Restartable;
|
||||
import org.springframework.batch.statistics.StatisticsProvider;
|
||||
import org.springframework.beans.factory.DisposableBean;
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.dao.DataAccessResourceFailureException;
|
||||
import org.springframework.transaction.support.TransactionSynchronization;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* XmlOutputTemplate is implementation of {@link OutputSource} which processes
|
||||
* XML output independently of technologies used for serializing value objects
|
||||
* to XML files. It has references only to interfaces, not concrete
|
||||
* implementations. It uses {@link ObjectOutputFactory} interface for getting
|
||||
* {@link ObjectOutput}, which is interface for writing value objects to the
|
||||
* output stream. So it's easy to plug-in any technology for serializing value
|
||||
* objects to XML files by implementing these interfaces. See implementations of
|
||||
* {@link ObjectOutputFactory} interface.
|
||||
* <p>
|
||||
* This output template also provides restart, statistics and transaction
|
||||
* features by implementing corresponding 'advice' interfaces.
|
||||
*
|
||||
* @author peter.zozom
|
||||
* @see ObjectOutput
|
||||
* @see ObjectOutputFactory
|
||||
*/
|
||||
public class XmlOutputSource implements OutputSource, Restartable, StatisticsProvider, TransactionSynchronization,
|
||||
DisposableBean {
|
||||
private static final Log log = LogFactory.getLog(XmlOutputSource.class);
|
||||
|
||||
private static final String DEFAULT_ENCODING = "UTF-8";
|
||||
|
||||
private ObjectOutputFactory outputFactory;
|
||||
|
||||
private String encoding = DEFAULT_ENCODING;
|
||||
|
||||
private Resource resource;
|
||||
|
||||
private Properties statistics = new Properties();
|
||||
|
||||
/*
|
||||
* Unique source name used to construct this xml reader input source -
|
||||
* specified by the configuration file.
|
||||
*/
|
||||
private String sourceName = null;
|
||||
|
||||
public static final String WRITTEN_STATISTICS_NAME = "Written";
|
||||
|
||||
public static final String RESTART_DATA_NAME = "xmloutputtemplate.currentRecordCount";
|
||||
|
||||
private OutputState state;
|
||||
|
||||
// Accessor method for the state object
|
||||
private OutputState getState() {
|
||||
if (state == null) {
|
||||
state = new OutputState();
|
||||
}
|
||||
return state;
|
||||
}
|
||||
|
||||
public void afterPropertiesSet() throws Exception {
|
||||
Assert.notNull(resource);
|
||||
Assert.state(resource.getFile().canWrite(), "Resource is not writable");
|
||||
}
|
||||
|
||||
/**
|
||||
* Setter for resource. Represents a file that can be written.
|
||||
*
|
||||
* @param resource
|
||||
*/
|
||||
public void setResource(Resource resource) {
|
||||
this.resource = resource;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize the output source. This method should be called for each
|
||||
* thread using same XmlOutputTemplate instance.
|
||||
*
|
||||
* @see org.springframework.batch.item.ResourceLifecycle#open()
|
||||
*/
|
||||
public void open() {
|
||||
|
||||
OutputState os = getState();
|
||||
if (!os.initialized) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers object for transaction synchronization
|
||||
*/
|
||||
protected void registerSynchronization() {
|
||||
BatchTransactionSynchronizationManager.registerSynchronization(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Just calls {@link #close()} so that bean factories will clean up
|
||||
* resources correctly.
|
||||
*
|
||||
* @see org.springframework.beans.factory.DisposableBean#destroy()
|
||||
*/
|
||||
public void destroy() throws Exception {
|
||||
close();
|
||||
}
|
||||
|
||||
/**
|
||||
* Close the output source
|
||||
*
|
||||
* @see org.springframework.batch.item.ResourceLifecycle#close()
|
||||
*/
|
||||
public void close() {
|
||||
OutputState os = getState();
|
||||
try {
|
||||
if (os != null && os.objectOutput != null) {
|
||||
os.objectOutput.close();
|
||||
}
|
||||
}
|
||||
finally {
|
||||
if (os != null) {
|
||||
os.initialized = false;
|
||||
os.restarted = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Initializes and obtains a ObjectOutput from ObjectOutputFactory.
|
||||
*/
|
||||
private void initializeXmlWriter() {
|
||||
OutputState os = getState();
|
||||
os.initialized = false;
|
||||
File file;
|
||||
|
||||
try {
|
||||
file = resource.getFile();
|
||||
|
||||
// If the output source was restarted, keep existing file.
|
||||
// If the output source was not restarted, check following:
|
||||
// - if the file should be deleted, delete it if it was exiting and
|
||||
// create blank file,
|
||||
// - if the file should not be deleted, if it already exists, throw
|
||||
// an exception,
|
||||
// - if the file was not existing, create new.
|
||||
if (!os.restarted) {
|
||||
if (file.exists()) {
|
||||
if (os.shouldDeleteIfExists) {
|
||||
file.delete();
|
||||
}
|
||||
else {
|
||||
throw new BatchEnvironmentException("Resource already exists: " + resource);
|
||||
}
|
||||
}
|
||||
file.createNewFile();
|
||||
}
|
||||
|
||||
}
|
||||
catch (IOException ioe) {
|
||||
log.error(ioe);
|
||||
throw new DataAccessResourceFailureException("Unable to write to file resource: [" + resource + "]", ioe);
|
||||
}
|
||||
|
||||
os.objectOutput = outputFactory.createObjectOutput(resource, encoding);
|
||||
|
||||
if (os.restarted) {
|
||||
os.objectOutput.afterRestart(new Long(os.lastMarkedByteOffsetPosition));
|
||||
checkFileSize();
|
||||
}
|
||||
|
||||
os.initialized = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Write the value object to output xml stream.
|
||||
* @param output the value object
|
||||
* @see org.springframework.batch.io.OutputSource#write(java.lang.Object)
|
||||
*/
|
||||
public void write(Object output) {
|
||||
OutputState os = getState();
|
||||
if (!os.initialized) {
|
||||
open();
|
||||
initializeXmlWriter();
|
||||
}
|
||||
|
||||
try {
|
||||
os.objectOutput.writeObject(output);
|
||||
os.objectsWritten++;
|
||||
}
|
||||
catch (IOException ioe) {
|
||||
log.error(ioe);
|
||||
throw new DataAccessResourceFailureException("Unable to write to ObjectOutputStream", ioe);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the name of the output source.
|
||||
*/
|
||||
public void setName(String newName) {
|
||||
this.sourceName = newName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the name of the output source.
|
||||
*
|
||||
* @see org.springframework.batch.restart.Restartable#getName()
|
||||
*/
|
||||
public String getName() {
|
||||
return sourceName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Postprocess after transaction commit/rollback. Called from transaction
|
||||
* manager.
|
||||
*
|
||||
* @param status indicates whether it was a rollback or commit
|
||||
*/
|
||||
public void afterCompletion(int status) {
|
||||
if (status == TransactionSynchronization.STATUS_COMMITTED) {
|
||||
transactionComitted();
|
||||
}
|
||||
else if (status == TransactionSynchronization.STATUS_ROLLED_BACK) {
|
||||
transactionRolledback();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Postprocess after transaction commit
|
||||
*/
|
||||
private void transactionComitted() {
|
||||
OutputState os = getState();
|
||||
|
||||
os.objectOutput.flush();
|
||||
os.lastMarkedByteOffsetPosition = this.position();
|
||||
}
|
||||
|
||||
/*
|
||||
* Postprocess after transaction rollback
|
||||
*/
|
||||
private void transactionRolledback() {
|
||||
checkFileSize();
|
||||
resetPositionForRestart();
|
||||
}
|
||||
|
||||
/*
|
||||
* This method removes any information in the file before this reset point.
|
||||
*
|
||||
* @param resetByteOffset a long integer representing the byte offset to
|
||||
* trunction and reposition the file cursor to for restarting.
|
||||
*/
|
||||
private void resetPositionForRestart() {
|
||||
OutputState os = getState();
|
||||
os.objectOutput.truncate(os.lastMarkedByteOffsetPosition);
|
||||
os.objectOutput.position(os.lastMarkedByteOffsetPosition);
|
||||
}
|
||||
|
||||
/*
|
||||
* Checks (on setState) to make sure that the current output file's size is
|
||||
* not smaller than the last saved commit point. If it is, then the file has
|
||||
* been damaged in some way and whole task must be started over again from
|
||||
* the beginning.
|
||||
*/
|
||||
private void checkFileSize() {
|
||||
OutputState os = getState();
|
||||
long size = -1;
|
||||
|
||||
size = os.objectOutput.size();
|
||||
|
||||
Assert.state(size >= os.lastMarkedByteOffsetPosition, "Current file size is smaller than size at last commit");
|
||||
}
|
||||
|
||||
/*
|
||||
* Return the byte offset position of the cursor in the output file as a
|
||||
* long integer.
|
||||
*
|
||||
* @return long integer representing the byte offset position of the cursor
|
||||
* in the output file.
|
||||
*/
|
||||
private long position() {
|
||||
OutputState os = getState();
|
||||
return os.objectOutput.position();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get statistics for the processed output.
|
||||
* @return actual statistics for the processed output
|
||||
* @see org.springframework.batch.container.advice.StatisticsAdvice#getStatistics()
|
||||
*/
|
||||
public Properties getStatistics() {
|
||||
|
||||
statistics.setProperty(WRITTEN_STATISTICS_NAME, new Long(getState().objectsWritten).toString());
|
||||
return statistics;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set encoding.
|
||||
* @param encoding the character encoding of the stream
|
||||
*/
|
||||
public void setEncoding(String encoding) {
|
||||
this.encoding = encoding;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the ObjectOutputFactory which is used for retrieving ObjectOutput
|
||||
* @param outputFactory the factory to use
|
||||
*/
|
||||
public void setOutputFactory(ObjectOutputFactory outputFactory) {
|
||||
this.outputFactory = outputFactory;
|
||||
}
|
||||
|
||||
/* *** Intentionally unimplemented methods *** */
|
||||
|
||||
public void suspend() {
|
||||
}
|
||||
|
||||
public void resume() {
|
||||
}
|
||||
|
||||
public void beforeCommit(boolean arg0) {
|
||||
}
|
||||
|
||||
public void beforeCompletion() {
|
||||
}
|
||||
|
||||
public void afterCommit() {
|
||||
}
|
||||
|
||||
/*
|
||||
* Value object holding state of the output source.
|
||||
*/
|
||||
private static class OutputState {
|
||||
private boolean initialized = false;
|
||||
|
||||
private ObjectOutput objectOutput;
|
||||
|
||||
private long lastMarkedByteOffsetPosition = 0;
|
||||
|
||||
private long objectsWritten = 0;
|
||||
|
||||
private boolean shouldDeleteIfExists = true;
|
||||
|
||||
private boolean restarted = false;
|
||||
|
||||
}
|
||||
|
||||
public void restoreFrom(RestartData data) {
|
||||
if (data == null || data.getProperties() == null ||
|
||||
data.getProperties().getProperty(RESTART_DATA_NAME) == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
OutputState os = getState();
|
||||
os.lastMarkedByteOffsetPosition = Long.parseLong(data.getProperties().getProperty(RESTART_DATA_NAME));
|
||||
os.restarted = true;
|
||||
initializeXmlWriter();
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns the restart data for the output source. It returns
|
||||
* the current byte offset position of the cursor in the output file which
|
||||
* can be used to re-initialze the batch job in case of restart.
|
||||
*
|
||||
* @see org.springframework.batch.container.Restartable#getRestartData()
|
||||
*/
|
||||
|
||||
public RestartData getRestartData() {
|
||||
Properties restartData = new Properties();
|
||||
restartData.setProperty(RESTART_DATA_NAME, new Long(position()).toString());
|
||||
return new GenericRestartData(restartData);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method initializes the output source for restart. It opens the
|
||||
* output file and position the xml writer according to information provided
|
||||
* by the restart data.
|
||||
*
|
||||
* @param restartData restart data information
|
||||
* @see org.springframework.batch.container.advice.RestartAdvice#initForRestart(java.lang.Object)
|
||||
*/
|
||||
public void initForRestart(Object restartData) {
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
<html>
|
||||
<body>
|
||||
<p>
|
||||
Infrastructure implementations of io xml concerns.
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,58 +0,0 @@
|
||||
/*
|
||||
* 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.io.xml.xstream;
|
||||
|
||||
/**
|
||||
* Represents alias for an attribute.
|
||||
* @author peter.zozom
|
||||
*/
|
||||
public class AttributeAlias {
|
||||
|
||||
private String alias;
|
||||
|
||||
private String attributeName;
|
||||
|
||||
/**
|
||||
* @return the alias
|
||||
*/
|
||||
public String getAlias() {
|
||||
return alias;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set alias for attribute
|
||||
* @param alias the alias itself
|
||||
*/
|
||||
public void setAlias(String alias) {
|
||||
this.alias = alias;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the attribute name
|
||||
*/
|
||||
public String getAttributeName() {
|
||||
return attributeName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the attribute name.
|
||||
* @param attributeName the name of the attribute
|
||||
*/
|
||||
public void setAttributeName(String attributeName) {
|
||||
this.attributeName = attributeName;
|
||||
}
|
||||
}
|
||||
@@ -1,58 +0,0 @@
|
||||
/*
|
||||
* 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.io.xml.xstream;
|
||||
|
||||
/**
|
||||
* Defines which XML attribute to use for a field or a specific type.
|
||||
* @author peter.zozom
|
||||
*/
|
||||
public class AttributeProperties {
|
||||
|
||||
private String type;
|
||||
|
||||
private String fieldName;
|
||||
|
||||
/**
|
||||
* @return the field name which will be rendered as XML attribute
|
||||
*/
|
||||
public String getFieldName() {
|
||||
return fieldName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the field to be rendered as XML attribute
|
||||
* @param fieldName the name of the field
|
||||
*/
|
||||
public void setFieldName(String fieldName) {
|
||||
this.fieldName = fieldName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the type
|
||||
*/
|
||||
public String getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set type to be used for XML attribute.
|
||||
* @param type the name of the type to be rendered as XML attribute
|
||||
*/
|
||||
public void setType(String type) {
|
||||
this.type = type;
|
||||
}
|
||||
}
|
||||
@@ -1,76 +0,0 @@
|
||||
/*
|
||||
* 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.io.xml.xstream;
|
||||
|
||||
/**
|
||||
* Represents mapping of a class to a shorter name to be used in XML elements.
|
||||
* @author peter.zozom
|
||||
*/
|
||||
public class ClassAlias {
|
||||
|
||||
private String name;
|
||||
|
||||
private String type;
|
||||
|
||||
private String defaultImplementation;
|
||||
|
||||
/**
|
||||
* @return the default implementation of the type
|
||||
*/
|
||||
public String getDefaultImplementation() {
|
||||
return defaultImplementation;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set default implementation of type to use.
|
||||
* @param defaultImplementation Default implementation of type to use if no
|
||||
* other specified.
|
||||
*/
|
||||
public void setDefaultImplementation(String defaultImplementation) {
|
||||
this.defaultImplementation = defaultImplementation;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return short name for the type
|
||||
*/
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set short name.
|
||||
* @param name the name to set
|
||||
*/
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return aliased type
|
||||
*/
|
||||
public String getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set aliased type.
|
||||
* @param type type to be aliased
|
||||
*/
|
||||
public void setType(String type) {
|
||||
this.type = type;
|
||||
}
|
||||
}
|
||||
@@ -1,61 +0,0 @@
|
||||
/*
|
||||
* 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.io.xml.xstream;
|
||||
|
||||
import com.thoughtworks.xstream.XStream;
|
||||
|
||||
/**
|
||||
* Represents converter to be registered for parsing. Converter acts as a
|
||||
* strategy for converting a particular type of class to XML and back again.
|
||||
*
|
||||
* @author peter.zozom
|
||||
*/
|
||||
|
||||
public class ConverterProperties {
|
||||
private String className;
|
||||
|
||||
private int priority = XStream.PRIORITY_NORMAL;
|
||||
|
||||
/**
|
||||
* @return converter class name
|
||||
*/
|
||||
protected String getClassName() {
|
||||
return className;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set converter class name.
|
||||
* @param className converter class name
|
||||
*/
|
||||
protected void setClassName(String className) {
|
||||
this.className = className;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return converter priority
|
||||
*/
|
||||
protected int getPriority() {
|
||||
return priority;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param priority converter priority
|
||||
*/
|
||||
protected void setPriority(int priority) {
|
||||
this.priority = priority;
|
||||
}
|
||||
}
|
||||
@@ -1,62 +0,0 @@
|
||||
/*
|
||||
* 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.io.xml.xstream;
|
||||
|
||||
/**
|
||||
* Defines default implementation of a class which should associated with an
|
||||
* object. Whenever XStream encounters an instance of this type, it will use the
|
||||
* default implementation instead. For example, java.util.ArrayList is the
|
||||
* default implementation of java.util.List.
|
||||
* @author peter.zozom
|
||||
*/
|
||||
public class DefaultImplementation {
|
||||
|
||||
private String defaultImpl;
|
||||
|
||||
private String type;
|
||||
|
||||
/**
|
||||
* @return class name of the default implementation
|
||||
*/
|
||||
public String getDefaultImpl() {
|
||||
return defaultImpl;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the class name of the default implementation which should be
|
||||
* associated with ofType.
|
||||
* @param defaultImpl class name of the default implementation
|
||||
*/
|
||||
public void setDefaultImpl(String defaultImpl) {
|
||||
this.defaultImpl = defaultImpl;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return type name associated with default implementation
|
||||
*/
|
||||
public String getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set type name which should be associated with default implementation.
|
||||
* @param ofType type name
|
||||
*/
|
||||
public void setType(String ofType) {
|
||||
this.type = ofType;
|
||||
}
|
||||
}
|
||||
@@ -1,74 +0,0 @@
|
||||
/*
|
||||
* 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.io.xml.xstream;
|
||||
|
||||
/**
|
||||
* Represents an alias for a field name.
|
||||
* @author peter.zozom
|
||||
*/
|
||||
public class FieldAlias {
|
||||
private String aliasName;
|
||||
|
||||
private String type;
|
||||
|
||||
private String fieldName;
|
||||
|
||||
/**
|
||||
* @return field alias
|
||||
*/
|
||||
public String getAliasName() {
|
||||
return aliasName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set field alias name.
|
||||
* @param aliasName the alias itself
|
||||
*/
|
||||
public void setAliasName(String aliasName) {
|
||||
this.aliasName = aliasName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return field name to be aliased
|
||||
*/
|
||||
public String getFieldName() {
|
||||
return fieldName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the name of the field to be aliased.
|
||||
* @param fieldName the name of the field to be aliased
|
||||
*/
|
||||
public void setFieldName(String fieldName) {
|
||||
this.fieldName = fieldName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the type that declares the field
|
||||
*/
|
||||
public String getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the type that declares the field.
|
||||
* @param type the type that declares the field
|
||||
*/
|
||||
public void setType(String type) {
|
||||
this.type = type;
|
||||
}
|
||||
}
|
||||
@@ -1,99 +0,0 @@
|
||||
/*
|
||||
* 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.io.xml.xstream;
|
||||
|
||||
/**
|
||||
* Represents implicit collection definition. Implicit collection is used for:
|
||||
* <ul>
|
||||
* <li>any unmapped xml tag</li>
|
||||
* <li>or all items of the given itemType</li>
|
||||
* <li>or all items of the given element name defined by itemFieldName</li>
|
||||
* </ul>
|
||||
*
|
||||
* @author peter.zozom
|
||||
*/
|
||||
public class ImplicitCollection {
|
||||
private String ownerType;
|
||||
|
||||
private String fieldName;
|
||||
|
||||
private String itemFieldName;
|
||||
|
||||
private String itemType;
|
||||
|
||||
/**
|
||||
* @return name of the field in the ownerType
|
||||
*/
|
||||
protected String getFieldName() {
|
||||
return fieldName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set name of the field in the owner class. This field must be an
|
||||
* <code>java.util.ArrayList</code>.
|
||||
* @param fieldName name of the field in the ownerType
|
||||
*/
|
||||
protected void setFieldName(String fieldName) {
|
||||
this.fieldName = fieldName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return element name of the implicit collection
|
||||
*/
|
||||
protected String getItemFieldName() {
|
||||
return itemFieldName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set element name of the implicit collection.
|
||||
* @param itemFieldName element name of the implicit collection
|
||||
*/
|
||||
protected void setItemFieldName(String itemFieldName) {
|
||||
this.itemFieldName = itemFieldName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return type of the items to be part of this collection
|
||||
*/
|
||||
protected String getItemType() {
|
||||
return itemType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set yype of the items to be part of this collection (aliased with
|
||||
* ItemFieldName, if provided).
|
||||
* @param itemType type of the items to be part of this collection
|
||||
*/
|
||||
protected void setItemType(String itemType) {
|
||||
this.itemType = itemType;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return class owning the implicit collection
|
||||
*/
|
||||
protected String getOwnerType() {
|
||||
return ownerType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set class that owns implicit collection.
|
||||
* @param ownerType class owning the implicit collection
|
||||
*/
|
||||
protected void setOwnerType(String ownerType) {
|
||||
this.ownerType = ownerType;
|
||||
}
|
||||
}
|
||||
@@ -1,98 +0,0 @@
|
||||
/*
|
||||
* 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.io.xml.xstream;
|
||||
|
||||
/**
|
||||
* Represents a mapping of qualified tag names to Java class names allowing
|
||||
* class aliases and namespace aware mappings of qualified tag names to class
|
||||
* names.
|
||||
* @author peter.zozom
|
||||
* @see javax.xml.namespace.QName
|
||||
*/
|
||||
public class Mapping {
|
||||
|
||||
private String namespaceURI;
|
||||
|
||||
private String localPart;
|
||||
|
||||
private String prefix;
|
||||
|
||||
private String className;
|
||||
|
||||
/**
|
||||
* @return class name
|
||||
*/
|
||||
public String getClassName() {
|
||||
return className;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set Java type which will be mapped.
|
||||
* @param className type name to be mapped
|
||||
*/
|
||||
public void setClassName(String className) {
|
||||
this.className = className;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return local part of the qualified name
|
||||
*/
|
||||
public String getLocalPart() {
|
||||
return localPart;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set local part of the qualified name.
|
||||
* @param localPart local part of the qualified name
|
||||
* @see javax.xml.namespace.QName
|
||||
*/
|
||||
public void setLocalPart(String localPart) {
|
||||
this.localPart = localPart;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return namespace URI of the qualified name
|
||||
*/
|
||||
public String getNamespaceURI() {
|
||||
return namespaceURI;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set namespace URI of the qualified name.
|
||||
* @param namespaceURI namespace URI of the qualified name
|
||||
* @see javax.xml.namespace.QName
|
||||
*/
|
||||
public void setNamespaceURI(String namespaceURI) {
|
||||
this.namespaceURI = namespaceURI;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return prefix of the qualified name
|
||||
*/
|
||||
public String getPrefix() {
|
||||
return prefix;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set prefix of the qualified name.
|
||||
* @param prefix prefix of the qualified name
|
||||
* @see javax.xml.namespace.QName
|
||||
*/
|
||||
public void setPrefix(String prefix) {
|
||||
this.prefix = prefix;
|
||||
}
|
||||
}
|
||||
@@ -1,60 +0,0 @@
|
||||
/*
|
||||
* 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.io.xml.xstream;
|
||||
|
||||
/**
|
||||
* Defines a field which shouldn't be serialized. To omit a field you must
|
||||
* always provide the declaring type and not necessarily the type that is
|
||||
* converted.
|
||||
* @author peter.zozom
|
||||
*
|
||||
*/
|
||||
public class OmmitedField {
|
||||
private String type;
|
||||
|
||||
private String fieldName;
|
||||
|
||||
/**
|
||||
* @return field which should be ommited
|
||||
*/
|
||||
protected String getFieldName() {
|
||||
return fieldName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set field which should be ommited.
|
||||
* @param fieldName field which should be ommited
|
||||
*/
|
||||
protected void setFieldName(String fieldName) {
|
||||
this.fieldName = fieldName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return declaring type of the ommited field
|
||||
*/
|
||||
protected String getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set declaring type of the ommited field.
|
||||
* @param type declaring type of the ommited field
|
||||
*/
|
||||
protected void setType(String type) {
|
||||
this.type = type;
|
||||
}
|
||||
}
|
||||
@@ -1,59 +0,0 @@
|
||||
/*
|
||||
* 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.io.xml.xstream;
|
||||
|
||||
/**
|
||||
* Represents mapping a type to a shorter name to be used in XML elements. Any
|
||||
* class that is assignable to this type will be aliased to the same name.
|
||||
* @author peter.zozom
|
||||
*/
|
||||
public class TypeAlias {
|
||||
|
||||
private String name;
|
||||
|
||||
private String type;
|
||||
|
||||
/**
|
||||
* @return short name for the type
|
||||
*/
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set short name.
|
||||
* @param name the name to set
|
||||
*/
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return aliased type
|
||||
*/
|
||||
public String getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set aliased type.
|
||||
* @param type type to be aliased
|
||||
*/
|
||||
public void setType(String type) {
|
||||
this.type = type;
|
||||
}
|
||||
}
|
||||
@@ -1,301 +0,0 @@
|
||||
/*
|
||||
* 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.io.xml.xstream;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import com.thoughtworks.xstream.XStream;
|
||||
|
||||
/**
|
||||
* Value object, which holds configuration for XStream.
|
||||
*
|
||||
* @author peter.zozom
|
||||
* @author Dave Syer
|
||||
*
|
||||
* @see XStreamConfigurationFactoryBean
|
||||
* @see Mapping
|
||||
* @see ClassAlias
|
||||
* @see TypeAlias
|
||||
* @see FieldAlias
|
||||
* @see AttributeAlias
|
||||
* @see AttributeProperties
|
||||
* @see ConverterProperties
|
||||
* @see XStream#setMode(int)
|
||||
* @see ImplicitCollection
|
||||
* @see OmmitedField
|
||||
* @see XStream#addImmutableType(Class)
|
||||
* @see DefaultImplementation
|
||||
*/
|
||||
public class XStreamConfiguration {
|
||||
|
||||
private List mappings = null;
|
||||
|
||||
private String rootElementName = null;
|
||||
|
||||
private Map rootElementAttributes;
|
||||
|
||||
private List classAliases = null;
|
||||
|
||||
private List typeAliases = null;
|
||||
|
||||
private List fieldAliases = null;
|
||||
|
||||
private List attributeAliases = null;
|
||||
|
||||
private List attributes = null;
|
||||
|
||||
private List converters = null;
|
||||
|
||||
private int mode = XStream.XPATH_RELATIVE_REFERENCES;
|
||||
|
||||
private List implicitCollections = null;
|
||||
|
||||
private List ommitedFields = null;
|
||||
|
||||
private List immutableTypes = null;
|
||||
|
||||
private List defaultImplementations = null;
|
||||
|
||||
/**
|
||||
* @return list of the {@link DefaultImplementation} objects
|
||||
*/
|
||||
public List getDefaultImplementations() {
|
||||
return defaultImplementations;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set list of default implementations.
|
||||
* @param defaultImplementations list of the {@link DefaultImplementation}
|
||||
* objects
|
||||
* @see DefaultImplementation
|
||||
*/
|
||||
public void setDefaultImplementations(List defaultImplementations) {
|
||||
this.defaultImplementations = defaultImplementations;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return list of the immutable type names
|
||||
*/
|
||||
public List getImmutableTypes() {
|
||||
return immutableTypes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set list of immutable types.
|
||||
* @param immutableTypes list of the immutable type names
|
||||
* @see XStream#addImmutableType(Class)
|
||||
*/
|
||||
public void setImmutableTypes(List immutableTypes) {
|
||||
this.immutableTypes = immutableTypes;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return list of the {@link AttributeAlias} objects
|
||||
*/
|
||||
public List getAttributeAliases() {
|
||||
return attributeAliases;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set list of attribute aliases.
|
||||
* @param attributeAliases list of the {@link AttributeAlias} objects
|
||||
* @see AttributeAlias
|
||||
*/
|
||||
public void setAttributeAliases(List attributeAliases) {
|
||||
this.attributeAliases = attributeAliases;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return list of the {@link AttributeProperties} objects
|
||||
*/
|
||||
public List getAttributes() {
|
||||
return attributes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set list of attribute properties.
|
||||
* @param attributes list of the {@link AttributeProperties}
|
||||
* objects
|
||||
* @see AttributeProperties
|
||||
*/
|
||||
public void setAttributes(List attributes) {
|
||||
this.attributes = attributes;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the classAliases
|
||||
*/
|
||||
public List getClassAliases() {
|
||||
return classAliases;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set list of class aliases.
|
||||
* @param classAliases the classAliases to set
|
||||
* @see ClassAlias
|
||||
*/
|
||||
public void setClassAliases(List classAliases) {
|
||||
this.classAliases = classAliases;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return list of the {@link ConverterProperties} objects
|
||||
*/
|
||||
public List getConverters() {
|
||||
return converters;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set list of custom converters.
|
||||
* @param converters list of the {@link ConverterProperties} objects
|
||||
* @see ConverterProperties
|
||||
*/
|
||||
public void setConverters(List converters) {
|
||||
this.converters = converters;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the fieldAliases
|
||||
*/
|
||||
public List getFieldAliases() {
|
||||
return fieldAliases;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set list of field aliases.
|
||||
* @param fieldAliases the list of fieldAliases to set
|
||||
* @see FieldAlias
|
||||
*/
|
||||
public void setFieldAliases(List fieldAliases) {
|
||||
this.fieldAliases = fieldAliases;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return list of the {@link ImplicitCollections} objects
|
||||
*/
|
||||
public List getImplicitCollections() {
|
||||
return implicitCollections;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set list of implicit collection definitions.
|
||||
* @param implicitCollections list of the {@link ImplicitCollections}
|
||||
* objects
|
||||
* @see ImplicitCollection
|
||||
*/
|
||||
public void setImplicitCollections(List implicitCollections) {
|
||||
this.implicitCollections = implicitCollections;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return list of the {@link Mapping} objects
|
||||
*/
|
||||
public List getMappings() {
|
||||
return mappings;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set list of "qualified tag name - to - class name" mappigs.
|
||||
* @param mappings list of the {@link Mapping} objects
|
||||
* @see Mapping
|
||||
*/
|
||||
public void setMappings(List mappings) {
|
||||
this.mappings = mappings;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the actual mode
|
||||
*/
|
||||
public int getMode() {
|
||||
return mode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set mode for dealing with duplicate references. If not provided, default
|
||||
* value is used ({@link XStream#XPATH_RELATIVE_REFERENCES}).
|
||||
* @param mode the mode to set
|
||||
* @see XStream#setMode(int)
|
||||
*/
|
||||
public void setMode(int mode) {
|
||||
this.mode = mode;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return list of the {@link OmmitedFields} objects
|
||||
*/
|
||||
public List getOmmitedFields() {
|
||||
return ommitedFields;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set list of ommited fields.
|
||||
* @param ommitedFields list of the {@link OmmitedFields} objects
|
||||
* @see OmmitedField
|
||||
*/
|
||||
public void setOmmitedFields(List ommitedFields) {
|
||||
this.ommitedFields = ommitedFields;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the root element attributes
|
||||
*/
|
||||
public Map getRootElementAttributes() {
|
||||
return rootElementAttributes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set attributes of root element. Each Map entry has key = "attribute name"
|
||||
* and value = "attribute value".
|
||||
* @param rootElementAttributes map of the root element attributes
|
||||
*/
|
||||
public void setRootElementAttributes(Map rootElementAttributes) {
|
||||
this.rootElementAttributes = rootElementAttributes;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the root element name
|
||||
*/
|
||||
public String getRootElementName() {
|
||||
return rootElementName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set name of the root element. Valid only for writing to XML.
|
||||
* @param rootElementName the root element name
|
||||
*/
|
||||
public void setRootElementName(String rootElementName) {
|
||||
this.rootElementName = rootElementName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the list of the {@link TypeAlias} objects
|
||||
*/
|
||||
public List getTypeAliases() {
|
||||
return typeAliases;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set list of type aliases.
|
||||
* @param typeAliases list of the {@link TypeAlias} objects
|
||||
* @see TypeAlias
|
||||
*/
|
||||
public void setTypeAliases(List typeAliases) {
|
||||
this.typeAliases = typeAliases;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,146 +0,0 @@
|
||||
/*
|
||||
* 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.io.xml.xstream;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.batch.io.exception.BatchEnvironmentException;
|
||||
import org.springframework.beans.factory.config.AbstractFactoryBean;
|
||||
import org.springframework.core.io.Resource;
|
||||
|
||||
import com.thoughtworks.xstream.XStream;
|
||||
|
||||
/**
|
||||
* Factory creates {@link XStreamConfiguration} object, which hold XStream's
|
||||
* configuration settings. These settings are read from provided configuration
|
||||
* XML file.
|
||||
*
|
||||
* @author peter.zozom
|
||||
* @author Dave Syer
|
||||
*/
|
||||
public class XStreamConfigurationFactoryBean extends AbstractFactoryBean {
|
||||
|
||||
private Log log = LogFactory.getLog(XStreamConfigurationFactoryBean.class);
|
||||
|
||||
private Resource resource;
|
||||
|
||||
/**
|
||||
* Creates {@link XStreamConfiguration} object from XStream's config file.
|
||||
* @return XStream's configuration settings.
|
||||
*/
|
||||
private XStreamConfiguration getXStreamConfiguration() {
|
||||
|
||||
XStream stream = new XStream();
|
||||
setConfigAliases(stream);
|
||||
|
||||
XStreamConfiguration xsc;
|
||||
try {
|
||||
InputStream is = resource.getInputStream();
|
||||
xsc = (XStreamConfiguration) stream.fromXML(is);
|
||||
is.close();
|
||||
}
|
||||
catch (IOException ioe) {
|
||||
log.debug(ioe);
|
||||
throw new BatchEnvironmentException("Could not read XStream mapping file.", ioe);
|
||||
}
|
||||
|
||||
return xsc;
|
||||
}
|
||||
|
||||
/*
|
||||
* Set aliases necessary for parsing configuration file in xstream format.
|
||||
*/
|
||||
private void setConfigAliases(XStream stream) {
|
||||
|
||||
stream.aliasField("root-element-name", XStreamConfiguration.class, "rootElementName");
|
||||
stream.aliasField("root-element-attributes", XStreamConfiguration.class, "rootElementAttributes");
|
||||
|
||||
stream.alias("class-alias", ClassAlias.class);
|
||||
stream.aliasField("default-implementation", ClassAlias.class, "defaultImplementation");
|
||||
stream.aliasField("class-aliases", XStreamConfiguration.class, "classAliases");
|
||||
|
||||
stream.alias("type-alias", TypeAlias.class);
|
||||
stream.aliasField("type-aliases", XStreamConfiguration.class, "typeAliases");
|
||||
|
||||
stream.alias("field-alias", FieldAlias.class);
|
||||
stream.aliasField("alias-name", FieldAlias.class, "aliasName");
|
||||
stream.aliasField("field-name", FieldAlias.class, "fieldName");
|
||||
stream.aliasField("field-aliases", XStreamConfiguration.class, "fieldAliases");
|
||||
|
||||
stream.alias("attribute-alias", AttributeAlias.class);
|
||||
stream.aliasField("attribute-name", AttributeAlias.class, "attributeName");
|
||||
stream.aliasField("attribute-aliases", XStreamConfiguration.class, "attributeAliases");
|
||||
|
||||
stream.alias("attribute-properties", AttributeProperties.class);
|
||||
stream.aliasField("field-name", AttributeProperties.class, "fieldName");
|
||||
stream.aliasField("attributes", XStreamConfiguration.class, "attributes");
|
||||
|
||||
stream.alias("converter-properties", ConverterProperties.class);
|
||||
stream.aliasField("class-name", ConverterProperties.class, "className");
|
||||
|
||||
stream.alias("implicit-collection", ImplicitCollection.class);
|
||||
stream.aliasField("owner-type", ImplicitCollection.class, "ownerType");
|
||||
stream.aliasField("item-type", ImplicitCollection.class, "itemType");
|
||||
stream.aliasField("field-name", ImplicitCollection.class, "fieldName");
|
||||
stream.aliasField("item-field-name", ImplicitCollection.class, "itemFieldName");
|
||||
stream.aliasField("implicit-collections", XStreamConfiguration.class, "implicitCollections");
|
||||
|
||||
stream.alias("ommited-field", OmmitedField.class);
|
||||
stream.aliasField("field-name", OmmitedField.class, "fieldName");
|
||||
stream.aliasField("ommited-fields", XStreamConfiguration.class, "ommitedFields");
|
||||
|
||||
stream.alias("default-implementation", DefaultImplementation.class);
|
||||
stream.aliasField("default-impl", DefaultImplementation.class, "defaultImpl");
|
||||
stream.aliasField("default-implementations", XStreamConfiguration.class, "defaultImplementations");
|
||||
|
||||
stream.aliasField("immutable-types", XStreamConfiguration.class, "immutableTypes");
|
||||
|
||||
stream.alias("attribute", Entry.class);
|
||||
stream.alias("mapping", Mapping.class);
|
||||
stream.aliasField("class-name", Mapping.class, "className");
|
||||
stream.alias("configuration", XStreamConfiguration.class);
|
||||
stream.alias("key", java.lang.String.class);
|
||||
stream.alias("value", java.lang.String.class);
|
||||
stream.alias("type", java.lang.String.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the filename of the configuration XML file.
|
||||
* @param configFile resource for reading configuration
|
||||
*/
|
||||
public void setConfigFile(Resource resource) {
|
||||
this.resource = resource;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.springframework.beans.factory.config.AbstractFactoryBean#createInstance()
|
||||
*/
|
||||
protected Object createInstance() throws Exception {
|
||||
return getXStreamConfiguration();
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.springframework.beans.factory.config.AbstractFactoryBean#getObjectType()
|
||||
*/
|
||||
public Class getObjectType() {
|
||||
return XStreamConfiguration.class;
|
||||
}
|
||||
}
|
||||
@@ -1,853 +0,0 @@
|
||||
/*
|
||||
* 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.io.xml.xstream;
|
||||
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.nio.channels.FileChannel;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.xml.namespace.QName;
|
||||
import javax.xml.stream.Location;
|
||||
import javax.xml.stream.XMLInputFactory;
|
||||
import javax.xml.stream.XMLOutputFactory;
|
||||
import javax.xml.stream.XMLStreamException;
|
||||
import javax.xml.stream.XMLStreamReader;
|
||||
import javax.xml.stream.XMLStreamWriter;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.batch.io.exception.BatchEnvironmentException;
|
||||
import org.springframework.batch.io.xml.ObjectInput;
|
||||
import org.springframework.batch.io.xml.ObjectInputFactory;
|
||||
import org.springframework.batch.io.xml.ObjectOutput;
|
||||
import org.springframework.batch.io.xml.ObjectOutputFactory;
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.dao.DataAccessResourceFailureException;
|
||||
|
||||
import com.thoughtworks.xstream.XStream;
|
||||
import com.thoughtworks.xstream.converters.Converter;
|
||||
import com.thoughtworks.xstream.converters.SingleValueConverter;
|
||||
import com.thoughtworks.xstream.io.xml.QNameMap;
|
||||
import com.thoughtworks.xstream.io.xml.StaxReader;
|
||||
import com.thoughtworks.xstream.io.xml.StaxWriter;
|
||||
|
||||
/**
|
||||
* XStreamFactory class implements both factory interfaces -
|
||||
* {@link ObjectInputFactory} and {@link ObjectOutputFactory}. Factory methods
|
||||
* {@link #createObjectInput(Resource, String)} and
|
||||
* {@link #createObjectOutput(Resource, String)} return implementations of
|
||||
* {@link ObjectInput} and {@link ObjectOutput} interfaces. These
|
||||
* implementations (ObjectInputWrapper and ObjecOutputWrapper) are defined as
|
||||
* factory's inner classes. They are wrapping StAX reader/writer for accessing
|
||||
* xml streams, XStream mapper for mapping Xml-to-ValueObjects and
|
||||
* {@link FileChannel} for file manipulation This factory implementation uses
|
||||
* {@link XStreamConfiguration} as source for XStream configuration settings.
|
||||
*
|
||||
* @author peter.zozom
|
||||
* @see ObjectInputFactory
|
||||
* @see ObjectOutputFactory
|
||||
* @see XStreamConfiguration
|
||||
*/
|
||||
public class XStreamFactory implements ObjectOutputFactory, ObjectInputFactory {
|
||||
private static final Log log = LogFactory.getLog(XStreamFactory.class);
|
||||
|
||||
private XStreamConfiguration config;
|
||||
|
||||
/**
|
||||
* Set the XStream's configuration.
|
||||
* @param config value object holding XStream's configuration settings
|
||||
*/
|
||||
public void setConfig(XStreamConfiguration config) {
|
||||
this.config = config;
|
||||
}
|
||||
|
||||
/*
|
||||
* Set up XStream. Proctected visibility modifier is used to allow easier
|
||||
* testing of set...() methods.
|
||||
*/
|
||||
protected void setUpXStream(XStream stream) {
|
||||
setClassAliases(stream);
|
||||
setTypeAliases(stream);
|
||||
setFieldAliases(stream);
|
||||
setAttributeAliases(stream);
|
||||
setAttributes(stream);
|
||||
registerConverters(stream);
|
||||
setMode(stream);
|
||||
addImplicitCollections(stream);
|
||||
setOmittedFileds(stream);
|
||||
addImmutableTypes(stream);
|
||||
addDefaultImplementations(stream);
|
||||
}
|
||||
|
||||
/*
|
||||
* Iterate over list of DefaultImplementation objects and add default
|
||||
* implementations to the XStream.
|
||||
*/
|
||||
private void addDefaultImplementations(XStream stream) {
|
||||
|
||||
// get list of DefaultImplementation objects
|
||||
List defaultImplementations = config.getDefaultImplementations();
|
||||
// if not null iterate over list
|
||||
if (defaultImplementations != null) {
|
||||
for (Iterator i = defaultImplementations.iterator(); i.hasNext();) {
|
||||
DefaultImplementation di = (DefaultImplementation) i.next();
|
||||
|
||||
// try to create Class object for default implementation class
|
||||
// name
|
||||
Class defaultImplementation;
|
||||
try {
|
||||
defaultImplementation = Class.forName(di.getDefaultImpl());
|
||||
}
|
||||
catch (ClassNotFoundException cnfe) {
|
||||
log.debug(cnfe);
|
||||
throw new BatchEnvironmentException("Unable to find class: " + di.getDefaultImpl(), cnfe);
|
||||
}
|
||||
|
||||
// try to create Class object for ofType class name
|
||||
Class ofType;
|
||||
try {
|
||||
ofType = Class.forName(di.getType());
|
||||
}
|
||||
catch (ClassNotFoundException cnfe) {
|
||||
log.debug(cnfe);
|
||||
throw new BatchEnvironmentException("Unable to find class: " + di.getType(), cnfe);
|
||||
}
|
||||
|
||||
// add default implementation
|
||||
stream.addDefaultImplementation(defaultImplementation, ofType);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Iterate over list of immutable type names and pass them to the XStream.
|
||||
*/
|
||||
private void addImmutableTypes(XStream stream) {
|
||||
// get list of names of immutable types
|
||||
List immutableTypes = config.getImmutableTypes();
|
||||
// if not null iterate over list
|
||||
if (immutableTypes != null) {
|
||||
for (Iterator i = immutableTypes.iterator(); i.hasNext();) {
|
||||
String it = (String) i.next();
|
||||
|
||||
// try to create Class object for immutableTypeName
|
||||
Class immutableType;
|
||||
try {
|
||||
immutableType = Class.forName(it);
|
||||
}
|
||||
catch (ClassNotFoundException cnfe) {
|
||||
log.debug(cnfe);
|
||||
throw new BatchEnvironmentException("Unable to find class: " + it, cnfe);
|
||||
}
|
||||
|
||||
// add immutable type
|
||||
stream.addImmutableType(immutableType);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* Iterate over list of OmmitField objects and register ommited fields to
|
||||
* the XStream.
|
||||
*/
|
||||
private void setOmittedFileds(XStream stream) {
|
||||
// get list of OmmitedField objects
|
||||
List ommitedFields = config.getOmmitedFields();
|
||||
// if not null iterate over list
|
||||
if (ommitedFields != null) {
|
||||
for (Iterator i = ommitedFields.iterator(); i.hasNext();) {
|
||||
OmmitedField ommitedField = (OmmitedField) i.next();
|
||||
|
||||
// register field to be ommited
|
||||
try {
|
||||
stream.omitField(Class.forName(ommitedField.getType()), ommitedField.getFieldName());
|
||||
}
|
||||
catch (ClassNotFoundException cnfe) {
|
||||
log.debug(cnfe);
|
||||
throw new BatchEnvironmentException("Unable to find class: " + ommitedField.getType(), cnfe);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Iterate over list of ImplicitCollection objects and add implicit
|
||||
* collections to the XStream. XStream has 3 methods for adding implicit
|
||||
* collections. Decision which method to call is based on provided settings.
|
||||
*/
|
||||
private void addImplicitCollections(XStream stream) {
|
||||
// get list of ImplicionCollection object
|
||||
List implicitCollections = config.getImplicitCollections();
|
||||
// if not null iterate over list
|
||||
if (implicitCollections != null) {
|
||||
for (Iterator i = implicitCollections.iterator(); i.hasNext();) {
|
||||
ImplicitCollection impCol = (ImplicitCollection) i.next();
|
||||
String typeName = impCol.getOwnerType();
|
||||
|
||||
// create Class object for typeName
|
||||
try {
|
||||
Class ownerType = Class.forName(typeName);
|
||||
|
||||
// if itemType not provided, add implicit collection for any
|
||||
// unmapped xml tag
|
||||
if (impCol.getItemType() == null) {
|
||||
stream.addImplicitCollection(ownerType, impCol.getFieldName());
|
||||
}
|
||||
else {
|
||||
typeName = impCol.getItemType();
|
||||
|
||||
// create Class object for itemType
|
||||
Class itemType = Class.forName(typeName);
|
||||
// if itemFieldName not provided, add implicit
|
||||
// collection for all items of the given itemType
|
||||
if (impCol.getItemFieldName() == null) {
|
||||
stream.addImplicitCollection(ownerType, impCol.getFieldName(), itemType);
|
||||
}
|
||||
else {
|
||||
// else add implicit collection for all items of the
|
||||
// given element name defined by itemFieldName
|
||||
stream.addImplicitCollection(ownerType, impCol.getFieldName(), impCol.getItemFieldName(),
|
||||
itemType);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (ClassNotFoundException cnfe) {
|
||||
log.debug(cnfe);
|
||||
throw new BatchEnvironmentException("Unable to find class: " + typeName, cnfe);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Set mode for dealing with duplicate references.
|
||||
*/
|
||||
private void setMode(XStream stream) {
|
||||
stream.setMode(config.getMode());
|
||||
}
|
||||
|
||||
/*
|
||||
* Iterate over list of ConverterProperties objects and register converters
|
||||
* to XStream.
|
||||
*/
|
||||
private void registerConverters(XStream stream) {
|
||||
// get list of ConverterProperties
|
||||
List converters = config.getConverters();
|
||||
// if not null iterate over list
|
||||
if (converters != null) {
|
||||
for (Iterator i = converters.iterator(); i.hasNext();) {
|
||||
ConverterProperties cp = (ConverterProperties) i.next();
|
||||
|
||||
// create Class object for converter class name
|
||||
try {
|
||||
Class converter = Class.forName(cp.getClassName());
|
||||
|
||||
// if converter type is assignable to SingleValueConverter,
|
||||
// register it as SingleValueConverter
|
||||
if (SingleValueConverter.class.isAssignableFrom(converter)) {
|
||||
stream.registerConverter((SingleValueConverter) converter.newInstance(), cp.getPriority());
|
||||
// if converter type is assignable to Converter,
|
||||
// register it as Converter
|
||||
}
|
||||
else if (Converter.class.isAssignableFrom(converter)) {
|
||||
stream.registerConverter((Converter) converter.newInstance(), cp.getPriority());
|
||||
}
|
||||
else {
|
||||
throw new BatchEnvironmentException("Unable to register converter for class: "
|
||||
+ cp.getClassName());
|
||||
}
|
||||
}
|
||||
catch (ClassNotFoundException cnfe) {
|
||||
log.debug(cnfe);
|
||||
throw new BatchEnvironmentException("Unable to find class: " + cp.getClassName(), cnfe);
|
||||
}
|
||||
catch (InstantiationException ie) {
|
||||
log.debug(ie);
|
||||
throw new BatchEnvironmentException("Unable to instantiate class: " + cp.getClassName(),
|
||||
ie);
|
||||
}
|
||||
catch (IllegalAccessException iae) {
|
||||
log.debug(iae);
|
||||
throw new BatchEnvironmentException("Unable to instantiate class: " + cp.getClassName(),
|
||||
iae);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Iterate over list of AttributeProperties objects and map XML attributes
|
||||
* to fields or types.
|
||||
*/
|
||||
private void setAttributes(XStream stream) {
|
||||
// get list of AttributeProperties objects
|
||||
List attributeProperties = config.getAttributes();
|
||||
// if not null iterate over list
|
||||
if (attributeProperties != null) {
|
||||
for (Iterator i = attributeProperties.iterator(); i.hasNext();) {
|
||||
AttributeProperties ap = (AttributeProperties) i.next();
|
||||
String fieldName = ap.getFieldName();
|
||||
|
||||
// create Class object for type name
|
||||
try {
|
||||
Class type = Class.forName(ap.getType());
|
||||
|
||||
// if field name is provided, map attribute to the field
|
||||
if (fieldName != null) {
|
||||
stream.useAttributeFor(fieldName, type);
|
||||
}
|
||||
else {
|
||||
// else map attribute to the type
|
||||
stream.useAttributeFor(type);
|
||||
}
|
||||
|
||||
}
|
||||
catch (ClassNotFoundException cnfe) {
|
||||
log.debug(cnfe);
|
||||
throw new BatchEnvironmentException("Unable to find class: " + ap.getType(), cnfe);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Iterate over list of AttributeAlias objects and configure attribute
|
||||
* aliases
|
||||
*/
|
||||
private void setAttributeAliases(XStream stream) {
|
||||
// get list of AttributeAlias objects
|
||||
List attributeAliases = config.getAttributeAliases();
|
||||
// if not null iterate over list
|
||||
if (attributeAliases != null) {
|
||||
for (Iterator i = attributeAliases.iterator(); i.hasNext();) {
|
||||
AttributeAlias alias = (AttributeAlias) i.next();
|
||||
stream.aliasAttribute(alias.getAlias(), alias.getAttributeName());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Iterate over list of FieldAlias objects and configure field aliases
|
||||
*/
|
||||
private void setFieldAliases(XStream stream) {
|
||||
// get list of FieldAlias objects
|
||||
List fieldAliases = config.getFieldAliases();
|
||||
// if not null iterate over list
|
||||
if (fieldAliases != null) {
|
||||
for (Iterator i = fieldAliases.iterator(); i.hasNext();) {
|
||||
FieldAlias alias = (FieldAlias) i.next();
|
||||
|
||||
try {
|
||||
stream.aliasField(alias.getAliasName(), Class.forName(alias.getType()), alias.getFieldName());
|
||||
}
|
||||
catch (ClassNotFoundException cnfe) {
|
||||
log.debug(cnfe);
|
||||
throw new BatchEnvironmentException("Unable to find class: " + alias.getType(), cnfe);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Iterate over list of TypeAlias objects and configure type aliases
|
||||
*/
|
||||
private void setTypeAliases(XStream stream) {
|
||||
// get list of TypeAlias objects
|
||||
List typeAliases = config.getTypeAliases();
|
||||
// if not null iterate over list
|
||||
if (typeAliases != null) {
|
||||
for (Iterator i = typeAliases.iterator(); i.hasNext();) {
|
||||
TypeAlias alias = (TypeAlias) i.next();
|
||||
|
||||
try {
|
||||
stream.aliasType(alias.getName(), Class.forName(alias.getType()));
|
||||
}
|
||||
catch (ClassNotFoundException cnfe) {
|
||||
log.debug(cnfe);
|
||||
throw new BatchEnvironmentException("Unable to find class: " + alias.getType(), cnfe);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Iterate over list of ClassAlias objects and configure class aliases
|
||||
*/
|
||||
private void setClassAliases(XStream stream) {
|
||||
// get list of ClassAlias objects
|
||||
List classAliases = config.getClassAliases();
|
||||
// if not null iterate over list
|
||||
if (classAliases != null) {
|
||||
for (Iterator i = classAliases.iterator(); i.hasNext();) {
|
||||
ClassAlias alias = (ClassAlias) i.next();
|
||||
|
||||
Class type;
|
||||
try {
|
||||
type = Class.forName(alias.getType());
|
||||
}
|
||||
catch (ClassNotFoundException cnfe) {
|
||||
log.debug(cnfe);
|
||||
throw new BatchEnvironmentException("Unable to find class: " + alias.getType(), cnfe);
|
||||
}
|
||||
|
||||
if (alias.getDefaultImplementation() != null) {
|
||||
Class defaultImplementation;
|
||||
try {
|
||||
defaultImplementation = Class.forName(alias.getDefaultImplementation());
|
||||
}
|
||||
catch (ClassNotFoundException cnfe) {
|
||||
log.debug(cnfe);
|
||||
throw new BatchEnvironmentException(
|
||||
"Unable to find class: " + alias.getDefaultImplementation(), cnfe);
|
||||
}
|
||||
|
||||
stream.alias(alias.getName(), type, defaultImplementation);
|
||||
}
|
||||
else {
|
||||
stream.alias(alias.getName(), type);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Create QNameMap from list of Mapping objects.
|
||||
*/
|
||||
private QNameMap getMapping() {
|
||||
|
||||
List mappings = config.getMappings();
|
||||
|
||||
QNameMap map = new QNameMap();
|
||||
|
||||
if (mappings != null) {
|
||||
for (Iterator i = mappings.iterator(); i.hasNext();) {
|
||||
Mapping mapping = (Mapping) i.next();
|
||||
QName qname = new QName(mapping.getNamespaceURI(), mapping.getLocalPart(), mapping.getPrefix());
|
||||
map.registerMapping(qname, mapping.getClassName());
|
||||
}
|
||||
}
|
||||
|
||||
return map;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates instance of {@link ObjectInput} which is used by
|
||||
* for deserializing object from XML file.
|
||||
* @param resource the input XML file
|
||||
* @param encoding the encoding to use
|
||||
* @return ObjectInput which will read from the provided file
|
||||
* @see org.springframework.batch.io.xml.ObjectInputFactory#createObjectInput(Resource,
|
||||
* java.lang.String)
|
||||
*/
|
||||
public ObjectInput createObjectInput(Resource resource, String encoding) {
|
||||
|
||||
ObjectInput wrapper;
|
||||
|
||||
XStream stream = new XStream();
|
||||
setUpXStream(stream);
|
||||
|
||||
try {
|
||||
XMLInputFactory xmlif = XMLInputFactory.newInstance();
|
||||
XMLStreamReader xmlReader = xmlif.createXMLStreamReader(resource.getInputStream(), encoding);
|
||||
|
||||
StaxReader reader = new StaxReader(getMapping(), xmlReader);
|
||||
java.io.ObjectInput input = stream.createObjectInputStream(reader);
|
||||
wrapper = new ObjectInputWrapper(xmlReader, input);
|
||||
}
|
||||
catch (XMLStreamException xse) {
|
||||
log.error(xse);
|
||||
throw new DataAccessResourceFailureException("Unable to get XML reader", xse);
|
||||
}
|
||||
catch (IOException ioe) {
|
||||
log.error(ioe);
|
||||
throw new DataAccessResourceFailureException("Unable to get ObjectInputStream", ioe);
|
||||
}
|
||||
|
||||
return wrapper;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates instance of {@link ObjectOutput} which is used by
|
||||
* for serializing object to XML file.
|
||||
* @param resource the output XML file
|
||||
* @param encoding the encoding to use
|
||||
* @return ObjectOutput which will write to the provided file
|
||||
* @see org.springframework.batch.io.xml.ObjectOutputFactory#createObjectOutput(Resource,
|
||||
* java.lang.String)
|
||||
*/
|
||||
public ObjectOutput createObjectOutput(Resource resource, String encoding) {
|
||||
|
||||
ObjectOutput wrapper;
|
||||
FileChannel channel;
|
||||
|
||||
XStream stream = new XStream();
|
||||
setUpXStream(stream);
|
||||
|
||||
try {
|
||||
XMLOutputFactory xmlof = XMLOutputFactory.newInstance();
|
||||
|
||||
FileOutputStream os;
|
||||
|
||||
try {
|
||||
os = new FileOutputStream(resource.getFile(), true);
|
||||
channel = os.getChannel();
|
||||
}
|
||||
catch (FileNotFoundException ioe) {
|
||||
log.error(ioe);
|
||||
throw new DataAccessResourceFailureException("Unable to write to file resource: [" + resource + "]",
|
||||
ioe);
|
||||
}
|
||||
|
||||
XMLStreamWriter xmlWriter = xmlof.createXMLStreamWriter(os, encoding);
|
||||
|
||||
StaxWriter writer = new StaxWriter(getMapping(), xmlWriter);
|
||||
String rootElementName = config.getRootElementName();
|
||||
java.io.ObjectOutput output;
|
||||
if (rootElementName != null) {
|
||||
output = stream.createObjectOutputStream(writer, rootElementName);
|
||||
}
|
||||
else {
|
||||
output = stream.createObjectOutputStream(writer);
|
||||
}
|
||||
|
||||
writeAttributes(xmlWriter, config.getRootElementAttributes());
|
||||
wrapper = new ObjectOutputWrapper(xmlWriter, channel, output);
|
||||
|
||||
}
|
||||
catch (XMLStreamException xse) {
|
||||
log.error(xse);
|
||||
throw new DataAccessResourceFailureException("Unable to get XML writer", xse);
|
||||
}
|
||||
catch (IOException ioe) {
|
||||
log.error(ioe);
|
||||
throw new DataAccessResourceFailureException("Unable to get ObjectOutputStream", ioe);
|
||||
}
|
||||
|
||||
return wrapper;
|
||||
}
|
||||
|
||||
/*
|
||||
* Writes attributes to current xml element
|
||||
*
|
||||
* @param attributes map of attributes (key, value) @throws
|
||||
* XMLStreamException
|
||||
*/
|
||||
private void writeAttributes(XMLStreamWriter xmlWriter, Map attributes) throws XMLStreamException {
|
||||
if ((attributes != null) && !attributes.isEmpty()) {
|
||||
|
||||
for (Iterator i = attributes.entrySet().iterator(); i.hasNext();) {
|
||||
Map.Entry entry = (Map.Entry) i.next();
|
||||
xmlWriter.writeAttribute((String) entry.getKey(), (String) entry.getValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of {@link ObjectInput} which wraps
|
||||
* {@link java.io.ObjectInput} and {@link XMLStreamReader} (which is StAX
|
||||
* parser) objects. Each of these objects handles the same input file on
|
||||
* different level and provides different set of methods:
|
||||
* <UL>
|
||||
* <LI>java.io.ObjectInput object is used for reading mapped objects</LI>
|
||||
* <LI>XMLStreamReader object is used for getting actual position (line
|
||||
* number) within xml file</LI>
|
||||
* </UL>
|
||||
*/
|
||||
public static class ObjectInputWrapper implements ObjectInput {
|
||||
|
||||
java.io.ObjectInput input;
|
||||
|
||||
XMLStreamReader reader;
|
||||
|
||||
/**
|
||||
* Postprocessing after restart. Current implementation does nothing.
|
||||
* @param data
|
||||
* @see org.springframework.batch.io.xml.ObjectInput#afterRestart(java.lang.Object)
|
||||
*/
|
||||
public void afterRestart(Object data) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param reader the xml stream reader
|
||||
* @param input the object input pointing to same file as reader
|
||||
*/
|
||||
public ObjectInputWrapper(XMLStreamReader reader, java.io.ObjectInput input) {
|
||||
this.input = input;
|
||||
this.reader = reader;
|
||||
}
|
||||
|
||||
/**
|
||||
* Close the object input. It closes all wraped input streams
|
||||
* @see org.springframework.batch.io.xml.ObjectInput#close()
|
||||
*/
|
||||
public void close() {
|
||||
try {
|
||||
input.close();
|
||||
reader.close();
|
||||
}
|
||||
catch (XMLStreamException xse) {
|
||||
log.error(xse);
|
||||
throw new DataAccessResourceFailureException("Unable to close XML Input Source", xse);
|
||||
}
|
||||
catch (IOException ioe) {
|
||||
log.error(ioe);
|
||||
throw new DataAccessResourceFailureException("Unable to close ObjectInputStream", ioe);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the current line number in the input stream.
|
||||
* @return the current line number
|
||||
* @see org.springframework.batch.io.xml.ObjectInput#position()
|
||||
*/
|
||||
public long position() {
|
||||
Location location = reader.getLocation();
|
||||
return location.getLineNumber();
|
||||
}
|
||||
|
||||
/**
|
||||
* Read and return an object.
|
||||
* @return the object read from the stream
|
||||
* @throws ClassNotFoundException If the class of a serialized bject
|
||||
* cannot be found.
|
||||
* @throws IOException If any of the usual Input/Output related
|
||||
* exceptions occur.
|
||||
* @see org.springframework.batch.io.xml.ObjectInput#readObject()
|
||||
*/
|
||||
public Object readObject() throws ClassNotFoundException, IOException {
|
||||
return input.readObject();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of ObjectOutput which wraps java.io.ObjectOutput,
|
||||
* XMLStreamWriter and FileChannel objects. Each of these objects handles
|
||||
* the same output file on different level and provides different set of
|
||||
* methods:
|
||||
* <UL>
|
||||
* <LI>java.io.ObjectOutput object is used for writing java objects to xml
|
||||
* output file</LI>
|
||||
* <LI>FileChannel object is used for file manipulation (truncate,
|
||||
* position, size)</LI>
|
||||
* <LI>XMLStreamWriter object is used for writing XML elements directly to
|
||||
* XML output stream</LI>
|
||||
* </UL>
|
||||
*/
|
||||
public static class ObjectOutputWrapper implements ObjectOutput {
|
||||
|
||||
java.io.ObjectOutput output;
|
||||
|
||||
XMLStreamWriter writer;
|
||||
|
||||
FileChannel channel;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param writer the xml stream writer
|
||||
* @param channel the file channel pointing to same file as writer
|
||||
* @param output the object output pointing to same file as writer
|
||||
*/
|
||||
public ObjectOutputWrapper(XMLStreamWriter writer, FileChannel channel, java.io.ObjectOutput output) {
|
||||
this.writer = writer;
|
||||
this.channel = channel;
|
||||
this.output = output;
|
||||
}
|
||||
|
||||
/**
|
||||
* Postprocessing after restart. It removes redundant xml header.
|
||||
* @param data java.lang.Long restart file position
|
||||
* @see org.springframework.batch.io.xml.ObjectOutput#afterRestart(java.lang.Object)
|
||||
*/
|
||||
public void afterRestart(Object data) {
|
||||
|
||||
long offset = ((Long) data).longValue();
|
||||
|
||||
// When xmlWriter is initialized, it always writes xml header and
|
||||
// opening tag of root element
|
||||
// but this is unwanted, because currently we are restarting job.
|
||||
// Header and opening
|
||||
// tag of root element have been already written at the beginning of
|
||||
// job processing.
|
||||
// Current output file looks like this:
|
||||
|
||||
// 1. <?xml version='1.0' encoding='utf-8'?>
|
||||
// 2. <root>
|
||||
// 3-n. .... <someRecords/> ....
|
||||
// n+1. </root>
|
||||
// n+2. <?xml version='1.0' encoding='utf-8'?>
|
||||
// n+3. <root
|
||||
|
||||
// Opening tag is not currently finished. We want to remove lines
|
||||
// n,n+1,n+2,n+3,...
|
||||
// offset is currently equal to position of beginning of line n+1.
|
||||
|
||||
// NOTE: openning tag of root element is always written when output
|
||||
// is being opened.
|
||||
// closing tag of root element is always written when output is
|
||||
// being closed.
|
||||
try {
|
||||
// At first we write some element to writer, e.g. empty comment.
|
||||
// This will change output like this:
|
||||
|
||||
// n+3. <root>
|
||||
// n+4. <!-- -->
|
||||
writer.writeComment("");
|
||||
// Now we flush output stream. Lines n+2,n+3,n+4 are now written
|
||||
// to the file.
|
||||
output.flush();
|
||||
}
|
||||
catch (IOException ioe) {
|
||||
log.error(ioe);
|
||||
throw new DataAccessResourceFailureException("Unable to write to ObjectOutputStream", ioe);
|
||||
}
|
||||
catch (XMLStreamException xse) {
|
||||
log.error(xse);
|
||||
throw new DataAccessResourceFailureException("Unable to get XML writer", xse);
|
||||
}
|
||||
|
||||
// Finally we truncate file size to lastMarkedByteOffsetPosition.
|
||||
// This will remove lines n+1 .. n+4.
|
||||
truncate(offset);
|
||||
position(offset);
|
||||
}
|
||||
|
||||
/**
|
||||
* Close the object output, which means to close all wrapped output
|
||||
* streams.
|
||||
* @see org.springframework.batch.io.xml.ObjectOutput#close()
|
||||
*/
|
||||
public void close() {
|
||||
try {
|
||||
output.close();
|
||||
writer.close();
|
||||
channel.close();
|
||||
}
|
||||
catch (XMLStreamException xse) {
|
||||
log.error(xse);
|
||||
throw new DataAccessResourceFailureException("Unable to close XML Output Source", xse);
|
||||
}
|
||||
catch (IOException ioe) {
|
||||
log.error(ioe);
|
||||
throw new DataAccessResourceFailureException("Unable to close ObjectOutputStream", ioe);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Flush the object output. This will write any buffered output bytes.
|
||||
* @see org.springframework.batch.io.xml.ObjectOutput#flush()
|
||||
*/
|
||||
public void flush() {
|
||||
try {
|
||||
output.flush();
|
||||
}
|
||||
catch (IOException ioe) {
|
||||
log.debug(ioe);
|
||||
throw new DataAccessResourceFailureException("An error occured while writing to XmlOutputSource", ioe);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve file position.
|
||||
* @return File position, a non-negative integer counting the number of
|
||||
* bytes from the beginning of the file to the current position
|
||||
* @see org.springframework.batch.io.xml.ObjectOutput#position()
|
||||
*/
|
||||
public long position() {
|
||||
long position = 0;
|
||||
|
||||
// flush buffer before getting position
|
||||
flush();
|
||||
|
||||
try {
|
||||
position = channel.position();
|
||||
}
|
||||
catch (IOException ioe) {
|
||||
log.debug(ioe);
|
||||
throw new DataAccessResourceFailureException("An error occured while writing to XmlOutputSource", ioe);
|
||||
}
|
||||
return position;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the file position.
|
||||
* @param newPosition The new position, a non-negative integer counting
|
||||
* the number of bytes from the beginning of the file
|
||||
* @see org.springframework.batch.io.xml.ObjectOutput#position(long)
|
||||
*/
|
||||
public void position(long newPosition) {
|
||||
try {
|
||||
channel.position(newPosition);
|
||||
}
|
||||
catch (IOException ioe) {
|
||||
log.error(ioe);
|
||||
throw new DataAccessResourceFailureException("An error occured while writing to XmlOutputSource", ioe);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the current size of the file.
|
||||
* @return The current size of the file, measured in bytes
|
||||
* @see org.springframework.batch.io.xml.ObjectOutput#size()
|
||||
*/
|
||||
public long size() {
|
||||
long size;
|
||||
|
||||
try {
|
||||
size = channel.size();
|
||||
}
|
||||
catch (IOException ioe) {
|
||||
log.debug(ioe);
|
||||
throw new DataAccessResourceFailureException("An error occured while writing to XmlOutputSource", ioe);
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
||||
/**
|
||||
* Truncates the file to the given size.
|
||||
* @param size The new size, a non-negative byte count
|
||||
* @see org.springframework.batch.io.xml.ObjectOutput#truncate(long)
|
||||
*/
|
||||
public void truncate(long size) {
|
||||
try {
|
||||
channel.truncate(size);
|
||||
}
|
||||
catch (IOException ioe) {
|
||||
log.error(ioe);
|
||||
throw new DataAccessResourceFailureException("An error occured while writing to XmlOutputSource", ioe);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Write object to the underlying stream.
|
||||
* @param obj the object to write
|
||||
* @throws IOException Any of the usual Input/Output related exceptions.
|
||||
* @see org.springframework.batch.io.xml.ObjectOutput#writeObject(java.lang.Object)
|
||||
*/
|
||||
public void writeObject(Object obj) throws IOException {
|
||||
output.writeObject(obj);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,569 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--xtools2_universal_type_manager-->
|
||||
<?com.ibm.xtools.emf.core.signature <signature id="com.ibm.xtools.mmi.ui.signatures.diagram" version="7.0.0"><feature description="" name="Rational Modeling Platform (com.ibm.xtools.rmp)" url="" version="7.0.0"/></signature>?>
|
||||
<notation:Diagram xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:notation="http://www.eclipse.org/gmf/runtime/1.0.0/notation" xmlns:uml="http://www.eclipse.org/uml2/2.0.0/UML" xmlns:umlnotation="http://www.ibm.com/xtools/1.5.2/Umlnotation" xmi:id="_zdRLcOgOEdu5GYaBl4l5qw" type="Class" name="XmlInputOutput.dnx">
|
||||
<children xmi:id="_3S6AQOgOEdu5GYaBl4l5qw">
|
||||
<children xmi:id="_3S6AQ-gOEdu5GYaBl4l5qw" type="ImageCompartment">
|
||||
<layoutConstraint xmi:type="notation:Size" xmi:id="_3S6AROgOEdu5GYaBl4l5qw" width="1320" height="1320"/>
|
||||
</children>
|
||||
<children xmi:id="_3S6ARegOEdu5GYaBl4l5qw" type="Stereotype"/>
|
||||
<children xmi:id="_3S6ARugOEdu5GYaBl4l5qw" type="Name"/>
|
||||
<children xmi:id="_3S6AR-gOEdu5GYaBl4l5qw" type="Parent"/>
|
||||
<children xmi:id="_3S6ASOgOEdu5GYaBl4l5qw" type="AttributeCompartment">
|
||||
<styles xmi:type="umlnotation:UMLListCompartmentStyle" xmi:id="_3S6ASegOEdu5GYaBl4l5qw" collapsed="true"/>
|
||||
</children>
|
||||
<children xmi:id="_3S6ASugOEdu5GYaBl4l5qw" type="OperationCompartment">
|
||||
<styles xmi:type="umlnotation:UMLListCompartmentStyle" xmi:id="_3S6AS-gOEdu5GYaBl4l5qw" collapsed="true"/>
|
||||
</children>
|
||||
<styles xmi:type="umlnotation:UMLShapeStyle" xmi:id="_3S6AQegOEdu5GYaBl4l5qw" lineColor="0" showStereotype="Label"/>
|
||||
<element xmi:type="uml:Class" href="mmi:///#jsrctype%5Ename=XmlInputTemplate%5Bjcu%5Ename=XmlInputTemplate.java%5Bjpack%5Ename=org.springframework.batch.container.io.file.xml.support%5Bjsrcroot%5Esrcfolder=src/main/java%5Bproject%5Eid=batch-breeze%5D%5D%5D%5D$uml.Class"/>
|
||||
<layoutConstraint xmi:type="notation:Bounds" xmi:id="_3S6AQugOEdu5GYaBl4l5qw" x="8745" y="343"/>
|
||||
</children>
|
||||
<children xmi:id="_6ojGYOgOEdu5GYaBl4l5qw">
|
||||
<children xmi:id="_6ojGY-gOEdu5GYaBl4l5qw" type="ImageCompartment">
|
||||
<layoutConstraint xmi:type="notation:Size" xmi:id="_6ojGZOgOEdu5GYaBl4l5qw" width="1320" height="1320"/>
|
||||
</children>
|
||||
<children xmi:id="_6ojGZegOEdu5GYaBl4l5qw" type="Stereotype"/>
|
||||
<children xmi:id="_6ojGZugOEdu5GYaBl4l5qw" type="Name"/>
|
||||
<children xmi:id="_6ojGZ-gOEdu5GYaBl4l5qw" type="Parent"/>
|
||||
<children xmi:id="_6ojGaOgOEdu5GYaBl4l5qw" type="AttributeCompartment">
|
||||
<styles xmi:type="umlnotation:UMLListCompartmentStyle" xmi:id="_6ojGaegOEdu5GYaBl4l5qw" collapsed="true"/>
|
||||
</children>
|
||||
<children xmi:id="_6ojGaugOEdu5GYaBl4l5qw" type="OperationCompartment">
|
||||
<styles xmi:type="umlnotation:UMLListCompartmentStyle" xmi:id="_6ojGa-gOEdu5GYaBl4l5qw" collapsed="true"/>
|
||||
</children>
|
||||
<styles xmi:type="umlnotation:UMLShapeStyle" xmi:id="_6ojGYegOEdu5GYaBl4l5qw" lineColor="0" showStereotype="Label"/>
|
||||
<element xmi:type="uml:Class" href="mmi:///#jsrctype%5Ename=XmlOutputTemplate%5Bjcu%5Ename=XmlOutputTemplate.java%5Bjpack%5Ename=org.springframework.batch.container.io.file.xml.support%5Bjsrcroot%5Esrcfolder=src/main/java%5Bproject%5Eid=batch-breeze%5D%5D%5D%5D$uml.Class"/>
|
||||
<layoutConstraint xmi:type="notation:Bounds" xmi:id="_6ojGYugOEdu5GYaBl4l5qw" x="15477" y="343"/>
|
||||
</children>
|
||||
<children xmi:id="_Az2LA-gPEdu5GYaBl4l5qw">
|
||||
<children xmi:id="_Az2LBugPEdu5GYaBl4l5qw" type="ImageCompartment">
|
||||
<layoutConstraint xmi:type="notation:Size" xmi:id="_Az2LB-gPEdu5GYaBl4l5qw" width="530" height="530"/>
|
||||
</children>
|
||||
<children xmi:id="_Az2LCOgPEdu5GYaBl4l5qw" type="Stereotype"/>
|
||||
<children xmi:id="_Az2LCegPEdu5GYaBl4l5qw" type="Kind"/>
|
||||
<children xmi:id="_Az2LCugPEdu5GYaBl4l5qw" type="Name"/>
|
||||
<children xmi:id="_Az2LC-gPEdu5GYaBl4l5qw" type="Parent"/>
|
||||
<children xmi:id="_Az2LDOgPEdu5GYaBl4l5qw" type="AttributeCompartment">
|
||||
<styles xmi:type="umlnotation:UMLListCompartmentStyle" xmi:id="_Az2LDegPEdu5GYaBl4l5qw"/>
|
||||
<layoutConstraint xmi:type="notation:Ratio" xmi:id="_Uio-IOhBEdu5GYaBl4l5qw" value="0.08968058968058969"/>
|
||||
</children>
|
||||
<children xmi:id="_Az2LDugPEdu5GYaBl4l5qw" type="OperationCompartment">
|
||||
<styles xmi:type="umlnotation:UMLListCompartmentStyle" xmi:id="_Az2LD-gPEdu5GYaBl4l5qw"/>
|
||||
<layoutConstraint xmi:type="notation:Ratio" xmi:id="_Uio-IehBEdu5GYaBl4l5qw" value="0.9103194103194103"/>
|
||||
</children>
|
||||
<styles xmi:type="umlnotation:UMLClassifierStyle" xmi:id="_Az2LBOgPEdu5GYaBl4l5qw" lineColor="128" showStereotype="Label" useClassifierShape="true"/>
|
||||
<element xmi:type="uml:Interface" href="mmi:///#jbintype%5Ename=java.io.ObjectInput%5Bproject%5Eid=batch-breeze%5D$uml.Interface"/>
|
||||
<layoutConstraint xmi:type="notation:Bounds" xmi:id="_Az2LBegPEdu5GYaBl4l5qw" x="1902" y="13314"/>
|
||||
</children>
|
||||
<children xmi:id="_kj8xUOgPEdu5GYaBl4l5qw">
|
||||
<children xmi:id="_kj8xU-gPEdu5GYaBl4l5qw" type="ImageCompartment">
|
||||
<layoutConstraint xmi:type="notation:Size" xmi:id="_kj8xVOgPEdu5GYaBl4l5qw" width="1320" height="1320"/>
|
||||
</children>
|
||||
<children xmi:id="_kj8xVegPEdu5GYaBl4l5qw" type="Stereotype"/>
|
||||
<children xmi:id="_kj8xVugPEdu5GYaBl4l5qw" type="Name"/>
|
||||
<children xmi:id="_kj8xV-gPEdu5GYaBl4l5qw" type="Parent"/>
|
||||
<children xmi:id="_kj8xWOgPEdu5GYaBl4l5qw" type="AttributeCompartment">
|
||||
<styles xmi:type="umlnotation:UMLListCompartmentStyle" xmi:id="_kj8xWegPEdu5GYaBl4l5qw" collapsed="true"/>
|
||||
</children>
|
||||
<children xmi:id="_kj8xWugPEdu5GYaBl4l5qw" type="OperationCompartment">
|
||||
<styles xmi:type="umlnotation:UMLListCompartmentStyle" xmi:id="_kj8xW-gPEdu5GYaBl4l5qw" collapsed="true"/>
|
||||
</children>
|
||||
<styles xmi:type="umlnotation:UMLShapeStyle" xmi:id="_kj8xUegPEdu5GYaBl4l5qw" lineColor="8404992" showStereotype="Label"/>
|
||||
<element xmi:type="uml:Class" href="mmi:///#jbintype%5Ename=com.thoughtworks.xstream.core.util.CustomObjectInputStream%5Bproject%5Eid=batch-breeze%5D$uml.Class"/>
|
||||
<layoutConstraint xmi:type="notation:Bounds" xmi:id="_kj8xUugPEdu5GYaBl4l5qw" x="951" y="22507"/>
|
||||
</children>
|
||||
<children xmi:id="_sfqDoegPEdu5GYaBl4l5qw">
|
||||
<children xmi:id="_sfqDpOgPEdu5GYaBl4l5qw" type="ImageCompartment">
|
||||
<layoutConstraint xmi:type="notation:Size" xmi:id="_sfqDpegPEdu5GYaBl4l5qw" width="1320" height="1320"/>
|
||||
</children>
|
||||
<children xmi:id="_sfqDpugPEdu5GYaBl4l5qw" type="Stereotype"/>
|
||||
<children xmi:id="_sfqDp-gPEdu5GYaBl4l5qw" type="Name"/>
|
||||
<children xmi:id="_sfqDqOgPEdu5GYaBl4l5qw" type="Parent"/>
|
||||
<children xmi:id="_sfqDqegPEdu5GYaBl4l5qw" type="AttributeCompartment">
|
||||
<styles xmi:type="umlnotation:UMLListCompartmentStyle" xmi:id="_sfqDqugPEdu5GYaBl4l5qw" collapsed="true"/>
|
||||
</children>
|
||||
<children xmi:id="_sfqDq-gPEdu5GYaBl4l5qw" type="OperationCompartment">
|
||||
<styles xmi:type="umlnotation:UMLListCompartmentStyle" xmi:id="_sfqDrOgPEdu5GYaBl4l5qw" collapsed="true"/>
|
||||
</children>
|
||||
<styles xmi:type="umlnotation:UMLShapeStyle" xmi:id="_sfqDougPEdu5GYaBl4l5qw" lineColor="8404992" showStereotype="Label"/>
|
||||
<element xmi:type="uml:Class" href="mmi:///#jbintype%5Ename=com.thoughtworks.xstream.core.util.CustomObjectOutputStream%5Bproject%5Eid=batch-breeze%5D$uml.Class"/>
|
||||
<layoutConstraint xmi:type="notation:Bounds" xmi:id="_sfqDo-gPEdu5GYaBl4l5qw" x="23458" y="22507"/>
|
||||
</children>
|
||||
<children xmi:id="_SFOp4OgoEdu5GYaBl4l5qw">
|
||||
<children xmi:id="_SFOp4-goEdu5GYaBl4l5qw" type="ImageCompartment">
|
||||
<layoutConstraint xmi:type="notation:Size" xmi:id="_SFOp5OgoEdu5GYaBl4l5qw" width="1320" height="1320"/>
|
||||
</children>
|
||||
<children xmi:id="_SFOp5egoEdu5GYaBl4l5qw" type="Stereotype"/>
|
||||
<children xmi:id="_SFOp5ugoEdu5GYaBl4l5qw" type="Name"/>
|
||||
<children xmi:id="_SFOp5-goEdu5GYaBl4l5qw" type="Parent"/>
|
||||
<children xmi:id="_SFUwgOgoEdu5GYaBl4l5qw" type="AttributeCompartment">
|
||||
<styles xmi:type="umlnotation:UMLListCompartmentStyle" xmi:id="_SFUwgegoEdu5GYaBl4l5qw" collapsed="true"/>
|
||||
</children>
|
||||
<children xmi:id="_SFUwgugoEdu5GYaBl4l5qw" type="OperationCompartment">
|
||||
<styles xmi:type="umlnotation:UMLListCompartmentStyle" xmi:id="_SFUwg-goEdu5GYaBl4l5qw" collapsed="true"/>
|
||||
</children>
|
||||
<styles xmi:type="umlnotation:UMLShapeStyle" xmi:id="_SFOp4egoEdu5GYaBl4l5qw" lineColor="128" showStereotype="Label"/>
|
||||
<element xmi:type="uml:Class" href="mmi:///#jbintype%5Ename=java.io.ObjectInputStream%5Bproject%5Eid=batch-breeze%5D$uml.Class"/>
|
||||
<layoutConstraint xmi:type="notation:Bounds" xmi:id="_SFOp4ugoEdu5GYaBl4l5qw" x="1320" y="18703"/>
|
||||
</children>
|
||||
<children xmi:id="_5ughMOgoEdu5GYaBl4l5qw" type="Note">
|
||||
<children xmi:id="_5ughM-goEdu5GYaBl4l5qw" type="DiagramName">
|
||||
<element xsi:nil="true"/>
|
||||
</children>
|
||||
<children xmi:id="_5ughNOgoEdu5GYaBl4l5qw" type="Description">
|
||||
<element xsi:nil="true"/>
|
||||
</children>
|
||||
<styles xmi:type="notation:ShapeStyle" xmi:id="_5ughMegoEdu5GYaBl4l5qw" fontColor="8388608" description="XStream's implementation of ObjectInputStream" fillColor="13369343" lineColor="12560536"/>
|
||||
<element xsi:nil="true"/>
|
||||
<layoutConstraint xmi:type="notation:Bounds" xmi:id="_5ughMugoEdu5GYaBl4l5qw" x="5389" y="20922" width="5051" height="1268"/>
|
||||
</children>
|
||||
<children xmi:id="_f0v4cOgpEdu5GYaBl4l5qw">
|
||||
<children xmi:id="_f0v4c-gpEdu5GYaBl4l5qw" type="ImageCompartment">
|
||||
<layoutConstraint xmi:type="notation:Size" xmi:id="_f0v4dOgpEdu5GYaBl4l5qw" width="530" height="530"/>
|
||||
</children>
|
||||
<children xmi:id="_f0v4degpEdu5GYaBl4l5qw" type="Stereotype"/>
|
||||
<children xmi:id="_f0v4dugpEdu5GYaBl4l5qw" type="Kind"/>
|
||||
<children xmi:id="_f0v4d-gpEdu5GYaBl4l5qw" type="Name"/>
|
||||
<children xmi:id="_f0v4eOgpEdu5GYaBl4l5qw" type="Parent"/>
|
||||
<children xmi:id="_f0v4eegpEdu5GYaBl4l5qw" type="AttributeCompartment">
|
||||
<styles xmi:type="umlnotation:UMLListCompartmentStyle" xmi:id="_f0v4eugpEdu5GYaBl4l5qw"/>
|
||||
</children>
|
||||
<children xmi:id="_f0v4e-gpEdu5GYaBl4l5qw" type="OperationCompartment">
|
||||
<styles xmi:type="umlnotation:UMLListCompartmentStyle" xmi:id="_f0v4fOgpEdu5GYaBl4l5qw"/>
|
||||
</children>
|
||||
<styles xmi:type="umlnotation:UMLClassifierStyle" xmi:id="_f0v4cegpEdu5GYaBl4l5qw" lineColor="128" showStereotype="Label" useClassifierShape="true"/>
|
||||
<element xmi:type="uml:Interface" href="mmi:///#jbintype%5Ename=java.io.ObjectOutput%5Bproject%5Eid=batch-breeze%5D$uml.Interface"/>
|
||||
<layoutConstraint xmi:type="notation:Bounds" xmi:id="_f0v4cugpEdu5GYaBl4l5qw" x="24409" y="13631"/>
|
||||
</children>
|
||||
<children xmi:id="_zY50kOgpEdu5GYaBl4l5qw">
|
||||
<children xmi:id="_zY50k-gpEdu5GYaBl4l5qw" type="ImageCompartment">
|
||||
<layoutConstraint xmi:type="notation:Size" xmi:id="_zY50lOgpEdu5GYaBl4l5qw" width="1320" height="1320"/>
|
||||
</children>
|
||||
<children xmi:id="_zY50legpEdu5GYaBl4l5qw" type="Stereotype"/>
|
||||
<children xmi:id="_zY50lugpEdu5GYaBl4l5qw" type="Name"/>
|
||||
<children xmi:id="_zY50l-gpEdu5GYaBl4l5qw" type="Parent"/>
|
||||
<children xmi:id="_zY50mOgpEdu5GYaBl4l5qw" type="AttributeCompartment">
|
||||
<styles xmi:type="umlnotation:UMLListCompartmentStyle" xmi:id="_zY50megpEdu5GYaBl4l5qw" collapsed="true"/>
|
||||
</children>
|
||||
<children xmi:id="_zY50mugpEdu5GYaBl4l5qw" type="OperationCompartment">
|
||||
<styles xmi:type="umlnotation:UMLListCompartmentStyle" xmi:id="_zY50m-gpEdu5GYaBl4l5qw" collapsed="true"/>
|
||||
</children>
|
||||
<styles xmi:type="umlnotation:UMLShapeStyle" xmi:id="_zY50kegpEdu5GYaBl4l5qw" lineColor="128" showStereotype="Label"/>
|
||||
<element xmi:type="uml:Class" href="mmi:///#jbintype%5Ename=java.io.ObjectOutputStream%5Bproject%5Eid=batch-breeze%5D$uml.Class"/>
|
||||
<layoutConstraint xmi:type="notation:Bounds" xmi:id="_zY50kugpEdu5GYaBl4l5qw" x="23775" y="18703"/>
|
||||
</children>
|
||||
<children xmi:id="_2S8j0OgpEdu5GYaBl4l5qw" type="Note">
|
||||
<children xmi:id="_2S8j0-gpEdu5GYaBl4l5qw" type="DiagramName">
|
||||
<element xsi:nil="true"/>
|
||||
</children>
|
||||
<children xmi:id="_2S8j1OgpEdu5GYaBl4l5qw" type="Description">
|
||||
<element xsi:nil="true"/>
|
||||
</children>
|
||||
<styles xmi:type="notation:ShapeStyle" xmi:id="_2S8j0egpEdu5GYaBl4l5qw" fontColor="8388608" description="XStream's implementation of ObjectOutputStream" fillColor="13369343" lineColor="12560536"/>
|
||||
<element xsi:nil="true"/>
|
||||
<layoutConstraint xmi:type="notation:Bounds" xmi:id="_2S8j0ugpEdu5GYaBl4l5qw" x="20288" y="20922" width="5051" height="1268"/>
|
||||
</children>
|
||||
<children xmi:id="_DdzUMOgtEdu5GYaBl4l5qw">
|
||||
<children xmi:id="_DdzUM-gtEdu5GYaBl4l5qw" type="ImageCompartment">
|
||||
<layoutConstraint xmi:type="notation:Size" xmi:id="_DdzUNOgtEdu5GYaBl4l5qw" width="1320" height="1320"/>
|
||||
</children>
|
||||
<children xmi:id="_DdzUNegtEdu5GYaBl4l5qw" type="Stereotype"/>
|
||||
<children xmi:id="_DdzUNugtEdu5GYaBl4l5qw" type="Name"/>
|
||||
<children xmi:id="_DdzUN-gtEdu5GYaBl4l5qw" type="Parent"/>
|
||||
<children xmi:id="_DdzUOOgtEdu5GYaBl4l5qw" type="AttributeCompartment">
|
||||
<styles xmi:type="umlnotation:UMLListCompartmentStyle" xmi:id="_DdzUOegtEdu5GYaBl4l5qw" collapsed="true"/>
|
||||
</children>
|
||||
<children xmi:id="_DdzUOugtEdu5GYaBl4l5qw" type="OperationCompartment">
|
||||
<styles xmi:type="umlnotation:UMLListCompartmentStyle" xmi:id="_DdzUO-gtEdu5GYaBl4l5qw" collapsed="true"/>
|
||||
</children>
|
||||
<styles xmi:type="umlnotation:UMLShapeStyle" xmi:id="_DdzUMegtEdu5GYaBl4l5qw" lineColor="8404992" showStereotype="Label"/>
|
||||
<element xmi:type="uml:Class" href="mmi:///#jsrctype%5Ename=XStreamConfiguration%5Bjcu%5Ename=XStreamConfiguration.java%5Bjpack%5Ename=org.springframework.batch.container.io.file.xml.support%5Bjsrcroot%5Esrcfolder=src/main/java%5Bproject%5Eid=batch-breeze%5D%5D%5D%5D$uml.Class"/>
|
||||
<layoutConstraint xmi:type="notation:Bounds" xmi:id="_DdzUMugtEdu5GYaBl4l5qw" x="12097" y="17778"/>
|
||||
</children>
|
||||
<children xmi:id="_2K50kOhJEdu5GYaBl4l5qw">
|
||||
<children xmi:id="_2K50k-hJEdu5GYaBl4l5qw" type="ImageCompartment">
|
||||
<layoutConstraint xmi:type="notation:Size" xmi:id="_2K50lOhJEdu5GYaBl4l5qw" width="530" height="530"/>
|
||||
</children>
|
||||
<children xmi:id="_2K50lehJEdu5GYaBl4l5qw" type="Stereotype"/>
|
||||
<children xmi:id="_2K50luhJEdu5GYaBl4l5qw" type="Kind"/>
|
||||
<children xmi:id="_2K50l-hJEdu5GYaBl4l5qw" type="Name"/>
|
||||
<children xmi:id="_2K50mOhJEdu5GYaBl4l5qw" type="Parent"/>
|
||||
<children xmi:id="_2K50mehJEdu5GYaBl4l5qw" type="AttributeCompartment">
|
||||
<styles xmi:type="umlnotation:UMLListCompartmentStyle" xmi:id="_2K50muhJEdu5GYaBl4l5qw"/>
|
||||
</children>
|
||||
<children xmi:id="_2K50m-hJEdu5GYaBl4l5qw" type="OperationCompartment">
|
||||
<styles xmi:type="umlnotation:UMLListCompartmentStyle" xmi:id="_2K50nOhJEdu5GYaBl4l5qw"/>
|
||||
</children>
|
||||
<styles xmi:type="umlnotation:UMLClassifierStyle" xmi:id="_2K50kehJEdu5GYaBl4l5qw" lineColor="0" showStereotype="Label" useClassifierShape="true"/>
|
||||
<element xmi:type="uml:Interface" href="mmi:///#jsrctype%5Ename=ObjectInput%5Bjcu%5Ename=ObjectInput.java%5Bjpack%5Ename=org.springframework.batch.container.io.file.xml.support%5Bjsrcroot%5Esrcfolder=src/main/java%5Bproject%5Eid=batch-breeze%5D%5D%5D%5D$uml.Interface"/>
|
||||
<layoutConstraint xmi:type="notation:Bounds" xmi:id="_2K50kuhJEdu5GYaBl4l5qw" x="1585" y="3804"/>
|
||||
</children>
|
||||
<children xmi:id="_2cYmIOhJEdu5GYaBl4l5qw">
|
||||
<children xmi:id="_2ceswOhJEdu5GYaBl4l5qw" type="ImageCompartment">
|
||||
<layoutConstraint xmi:type="notation:Size" xmi:id="_2ceswehJEdu5GYaBl4l5qw" width="530" height="530"/>
|
||||
</children>
|
||||
<children xmi:id="_2ceswuhJEdu5GYaBl4l5qw" type="Stereotype"/>
|
||||
<children xmi:id="_2cesw-hJEdu5GYaBl4l5qw" type="Kind"/>
|
||||
<children xmi:id="_2cesxOhJEdu5GYaBl4l5qw" type="Name"/>
|
||||
<children xmi:id="_2cesxehJEdu5GYaBl4l5qw" type="Parent"/>
|
||||
<children xmi:id="_2cesxuhJEdu5GYaBl4l5qw" type="AttributeCompartment">
|
||||
<styles xmi:type="umlnotation:UMLListCompartmentStyle" xmi:id="_2cesx-hJEdu5GYaBl4l5qw"/>
|
||||
</children>
|
||||
<children xmi:id="_2cesyOhJEdu5GYaBl4l5qw" type="OperationCompartment">
|
||||
<styles xmi:type="umlnotation:UMLListCompartmentStyle" xmi:id="_2cesyehJEdu5GYaBl4l5qw"/>
|
||||
</children>
|
||||
<styles xmi:type="umlnotation:UMLClassifierStyle" xmi:id="_2cYmIehJEdu5GYaBl4l5qw" lineColor="0" showStereotype="Label" useClassifierShape="true"/>
|
||||
<element xmi:type="uml:Interface" href="mmi:///#jsrctype%5Ename=ObjectOutput%5Bjcu%5Ename=ObjectOutput.java%5Bjpack%5Ename=org.springframework.batch.container.io.file.xml.support%5Bjsrcroot%5Esrcfolder=src/main/java%5Bproject%5Eid=batch-breeze%5D%5D%5D%5D$uml.Interface"/>
|
||||
<layoutConstraint xmi:type="notation:Bounds" xmi:id="_2cYmIuhJEdu5GYaBl4l5qw" x="24092" y="3170"/>
|
||||
</children>
|
||||
<children xmi:id="_6EjmsOhJEdu5GYaBl4l5qw">
|
||||
<children xmi:id="_6Ejms-hJEdu5GYaBl4l5qw" type="ImageCompartment">
|
||||
<layoutConstraint xmi:type="notation:Size" xmi:id="_6EjmtOhJEdu5GYaBl4l5qw" width="530" height="530"/>
|
||||
</children>
|
||||
<children xmi:id="_6EjmtehJEdu5GYaBl4l5qw" type="Stereotype"/>
|
||||
<children xmi:id="_6EjmtuhJEdu5GYaBl4l5qw" type="Kind"/>
|
||||
<children xmi:id="_6Ejmt-hJEdu5GYaBl4l5qw" type="Name"/>
|
||||
<children xmi:id="_6EjmuOhJEdu5GYaBl4l5qw" type="Parent"/>
|
||||
<children xmi:id="_6EjmuehJEdu5GYaBl4l5qw" type="AttributeCompartment">
|
||||
<styles xmi:type="umlnotation:UMLListCompartmentStyle" xmi:id="_6EjmuuhJEdu5GYaBl4l5qw"/>
|
||||
</children>
|
||||
<children xmi:id="_6Ejmu-hJEdu5GYaBl4l5qw" type="OperationCompartment">
|
||||
<styles xmi:type="umlnotation:UMLListCompartmentStyle" xmi:id="_6EjmvOhJEdu5GYaBl4l5qw"/>
|
||||
</children>
|
||||
<styles xmi:type="umlnotation:UMLClassifierStyle" xmi:id="_6EjmsehJEdu5GYaBl4l5qw" lineColor="0" showStereotype="Label" useClassifierShape="true"/>
|
||||
<element xmi:type="uml:Interface" href="mmi:///#jsrctype%5Ename=ObjectInputFactory%5Bjcu%5Ename=ObjectInputFactory.java%5Bjpack%5Ename=org.springframework.batch.container.io.file.xml.support%5Bjsrcroot%5Esrcfolder=src/main/java%5Bproject%5Eid=batch-breeze%5D%5D%5D%5D$uml.Interface"/>
|
||||
<layoutConstraint xmi:type="notation:Bounds" xmi:id="_6EjmsuhJEdu5GYaBl4l5qw" x="8559" y="4438"/>
|
||||
</children>
|
||||
<children xmi:id="_9tli4OhJEdu5GYaBl4l5qw">
|
||||
<children xmi:id="_9tli4-hJEdu5GYaBl4l5qw" type="ImageCompartment">
|
||||
<layoutConstraint xmi:type="notation:Size" xmi:id="_9tli5OhJEdu5GYaBl4l5qw" width="530" height="530"/>
|
||||
</children>
|
||||
<children xmi:id="_9tli5ehJEdu5GYaBl4l5qw" type="Stereotype"/>
|
||||
<children xmi:id="_9tli5uhJEdu5GYaBl4l5qw" type="Kind"/>
|
||||
<children xmi:id="_9tli5-hJEdu5GYaBl4l5qw" type="Name"/>
|
||||
<children xmi:id="_9tli6OhJEdu5GYaBl4l5qw" type="Parent"/>
|
||||
<children xmi:id="_9tli6ehJEdu5GYaBl4l5qw" type="AttributeCompartment">
|
||||
<styles xmi:type="umlnotation:UMLListCompartmentStyle" xmi:id="_9tli6uhJEdu5GYaBl4l5qw"/>
|
||||
</children>
|
||||
<children xmi:id="_9tli6-hJEdu5GYaBl4l5qw" type="OperationCompartment">
|
||||
<styles xmi:type="umlnotation:UMLListCompartmentStyle" xmi:id="_9tli7OhJEdu5GYaBl4l5qw"/>
|
||||
</children>
|
||||
<styles xmi:type="umlnotation:UMLClassifierStyle" xmi:id="_9tli4ehJEdu5GYaBl4l5qw" lineColor="0" showStereotype="Label" useClassifierShape="true"/>
|
||||
<element xmi:type="uml:Interface" href="mmi:///#jsrctype%5Ename=ObjectOutputFactory%5Bjcu%5Ename=ObjectOutputFactory.java%5Bjpack%5Ename=org.springframework.batch.container.io.file.xml.support%5Bjsrcroot%5Esrcfolder=src/main/java%5Bproject%5Eid=batch-breeze%5D%5D%5D%5D$uml.Interface"/>
|
||||
<layoutConstraint xmi:type="notation:Bounds" xmi:id="_9tli4uhJEdu5GYaBl4l5qw" x="15533" y="4438"/>
|
||||
</children>
|
||||
<children xmi:id="_KaIuAOhKEdu5GYaBl4l5qw">
|
||||
<children xmi:id="_KaIuA-hKEdu5GYaBl4l5qw" type="ImageCompartment">
|
||||
<layoutConstraint xmi:type="notation:Size" xmi:id="_KaIuBOhKEdu5GYaBl4l5qw" width="1320" height="1320"/>
|
||||
</children>
|
||||
<children xmi:id="_KaIuBehKEdu5GYaBl4l5qw" type="Stereotype"/>
|
||||
<children xmi:id="_KaIuBuhKEdu5GYaBl4l5qw" type="Name"/>
|
||||
<children xmi:id="_KaIuB-hKEdu5GYaBl4l5qw" type="Parent"/>
|
||||
<children xmi:id="_KaIuCOhKEdu5GYaBl4l5qw" type="AttributeCompartment">
|
||||
<styles xmi:type="umlnotation:UMLListCompartmentStyle" xmi:id="_KaIuCehKEdu5GYaBl4l5qw" collapsed="true"/>
|
||||
</children>
|
||||
<children xmi:id="_KaIuCuhKEdu5GYaBl4l5qw" type="OperationCompartment">
|
||||
<styles xmi:type="umlnotation:UMLListCompartmentStyle" xmi:id="_KaIuC-hKEdu5GYaBl4l5qw" collapsed="true"/>
|
||||
</children>
|
||||
<styles xmi:type="umlnotation:UMLShapeStyle" xmi:id="_KaIuAehKEdu5GYaBl4l5qw" lineColor="8404992" showStereotype="Label"/>
|
||||
<element xmi:type="uml:Class" href="mmi:///#jsrctype%5Ename=ObjectInputWrapper%5Bjsrctype%5Ename=XStreamFactory%5Bjcu%5Ename=XStreamFactory.java%5Bjpack%5Ename=org.springframework.batch.container.io.file.xml.support%5Bjsrcroot%5Esrcfolder=src/main/java%5Bproject%5Eid=batch-breeze%5D%5D%5D%5D%5D$uml.Class"/>
|
||||
<layoutConstraint xmi:type="notation:Bounds" xmi:id="_KaIuAuhKEdu5GYaBl4l5qw" x="8559" y="14582"/>
|
||||
</children>
|
||||
<children xmi:id="_KaIuDOhKEdu5GYaBl4l5qw">
|
||||
<children xmi:id="_KaIuD-hKEdu5GYaBl4l5qw" type="ImageCompartment">
|
||||
<layoutConstraint xmi:type="notation:Size" xmi:id="_KaIuEOhKEdu5GYaBl4l5qw" width="1320" height="1320"/>
|
||||
</children>
|
||||
<children xmi:id="_KaIuEehKEdu5GYaBl4l5qw" type="Stereotype"/>
|
||||
<children xmi:id="_KaIuEuhKEdu5GYaBl4l5qw" type="Name"/>
|
||||
<children xmi:id="_KaIuE-hKEdu5GYaBl4l5qw" type="Parent"/>
|
||||
<children xmi:id="_KaIuFOhKEdu5GYaBl4l5qw" type="AttributeCompartment">
|
||||
<styles xmi:type="umlnotation:UMLListCompartmentStyle" xmi:id="_KaIuFehKEdu5GYaBl4l5qw" collapsed="true"/>
|
||||
</children>
|
||||
<children xmi:id="_KaIuFuhKEdu5GYaBl4l5qw" type="OperationCompartment">
|
||||
<styles xmi:type="umlnotation:UMLListCompartmentStyle" xmi:id="_KaIuF-hKEdu5GYaBl4l5qw" collapsed="true"/>
|
||||
</children>
|
||||
<styles xmi:type="umlnotation:UMLShapeStyle" xmi:id="_KaIuDehKEdu5GYaBl4l5qw" lineColor="8404992" showStereotype="Label"/>
|
||||
<element xmi:type="uml:Class" href="mmi:///#jsrctype%5Ename=ObjectOutputWrapper%5Bjsrctype%5Ename=XStreamFactory%5Bjcu%5Ename=XStreamFactory.java%5Bjpack%5Ename=org.springframework.batch.container.io.file.xml.support%5Bjsrcroot%5Esrcfolder=src/main/java%5Bproject%5Eid=batch-breeze%5D%5D%5D%5D%5D$uml.Class"/>
|
||||
<layoutConstraint xmi:type="notation:Bounds" xmi:id="_KaIuDuhKEdu5GYaBl4l5qw" x="15348" y="14634"/>
|
||||
</children>
|
||||
<children xmi:id="_KaIuGOhKEdu5GYaBl4l5qw">
|
||||
<children xmi:id="_KaIuG-hKEdu5GYaBl4l5qw" type="ImageCompartment">
|
||||
<layoutConstraint xmi:type="notation:Size" xmi:id="_KaIuHOhKEdu5GYaBl4l5qw" width="1320" height="1320"/>
|
||||
</children>
|
||||
<children xmi:id="_KaIuHehKEdu5GYaBl4l5qw" type="Stereotype"/>
|
||||
<children xmi:id="_KaIuHuhKEdu5GYaBl4l5qw" type="Name"/>
|
||||
<children xmi:id="_KaIuH-hKEdu5GYaBl4l5qw" type="Parent"/>
|
||||
<children xmi:id="_KaIuIOhKEdu5GYaBl4l5qw" type="AttributeCompartment">
|
||||
<styles xmi:type="umlnotation:UMLListCompartmentStyle" xmi:id="_KaIuIehKEdu5GYaBl4l5qw" collapsed="true"/>
|
||||
</children>
|
||||
<children xmi:id="_KaIuIuhKEdu5GYaBl4l5qw" type="OperationCompartment">
|
||||
<styles xmi:type="umlnotation:UMLListCompartmentStyle" xmi:id="_KaIuI-hKEdu5GYaBl4l5qw" collapsed="true"/>
|
||||
</children>
|
||||
<styles xmi:type="umlnotation:UMLShapeStyle" xmi:id="_KaIuGehKEdu5GYaBl4l5qw" lineColor="8404992" showStereotype="Label"/>
|
||||
<element xmi:type="uml:Class" href="mmi:///#jsrctype%5Ename=XStreamFactory%5Bjcu%5Ename=XStreamFactory.java%5Bjpack%5Ename=org.springframework.batch.container.io.file.xml.support%5Bjsrcroot%5Esrcfolder=src/main/java%5Bproject%5Eid=batch-breeze%5D%5D%5D%5D$uml.Class"/>
|
||||
<layoutConstraint xmi:type="notation:Bounds" xmi:id="_KaIuGuhKEdu5GYaBl4l5qw" x="12626" y="11491"/>
|
||||
</children>
|
||||
<children xmi:id="_PFLQoOjVEduS0q4MIMV9Cw">
|
||||
<children xmi:id="_PFLQo-jVEduS0q4MIMV9Cw" type="ImageCompartment">
|
||||
<layoutConstraint xmi:type="notation:Size" xmi:id="_PFLQpOjVEduS0q4MIMV9Cw" width="1320" height="1320"/>
|
||||
</children>
|
||||
<children xmi:id="_PFRXQOjVEduS0q4MIMV9Cw" type="Stereotype"/>
|
||||
<children xmi:id="_PFRXQejVEduS0q4MIMV9Cw" type="Name"/>
|
||||
<children xmi:id="_PFRXQujVEduS0q4MIMV9Cw" type="Parent"/>
|
||||
<children xmi:id="_PFRXQ-jVEduS0q4MIMV9Cw" type="AttributeCompartment">
|
||||
<styles xmi:type="umlnotation:UMLListCompartmentStyle" xmi:id="_PFRXROjVEduS0q4MIMV9Cw" collapsed="true"/>
|
||||
</children>
|
||||
<children xmi:id="_PFRXRejVEduS0q4MIMV9Cw" type="OperationCompartment">
|
||||
<styles xmi:type="umlnotation:UMLListCompartmentStyle" xmi:id="_PFRXRujVEduS0q4MIMV9Cw" collapsed="true"/>
|
||||
</children>
|
||||
<styles xmi:type="umlnotation:UMLShapeStyle" xmi:id="_PFLQoejVEduS0q4MIMV9Cw" lineColor="8404992" showStereotype="Label"/>
|
||||
<element xmi:type="uml:Class" href="mmi:///#jsrctype%5Ename=XStreamConfigurationFactory%5Bjcu%5Ename=XStreamConfigurationFactory.java%5Bjpack%5Ename=org.springframework.batch.container.io.file.xml.support%5Bjsrcroot%5Esrcfolder=src/main/java%5Bproject%5Eid=batch-breeze%5D%5D%5D%5D$uml.Class"/>
|
||||
<layoutConstraint xmi:type="notation:Bounds" xmi:id="_PFLQoujVEduS0q4MIMV9Cw" x="11501" y="21239"/>
|
||||
</children>
|
||||
<children xmi:id="_zKpaAOv2EduQz8RnORu8xQ" type="Note">
|
||||
<children xmi:id="_zK7t4Ov2EduQz8RnORu8xQ" type="DiagramName">
|
||||
<element xsi:nil="true"/>
|
||||
</children>
|
||||
<children xmi:id="_zK7t4ev2EduQz8RnORu8xQ" type="Description">
|
||||
<element xsi:nil="true"/>
|
||||
</children>
|
||||
<styles xmi:type="notation:ShapeStyle" xmi:id="_zKpaAev2EduQz8RnORu8xQ" fontColor="128" description="package java.io" fillColor="13369343" lineColor="10265827"/>
|
||||
<element xsi:nil="true"/>
|
||||
<layoutConstraint xmi:type="notation:Bounds" xmi:id="_zKpaAuv2EduQz8RnORu8xQ" x="2219" y="11729" height="794"/>
|
||||
</children>
|
||||
<children xmi:id="_3-8PcOv2EduQz8RnORu8xQ" type="Note">
|
||||
<children xmi:id="_3-8Pcev2EduQz8RnORu8xQ" type="DiagramName">
|
||||
<element xsi:nil="true"/>
|
||||
</children>
|
||||
<children xmi:id="_3-8Pcuv2EduQz8RnORu8xQ" type="Description">
|
||||
<element xsi:nil="true"/>
|
||||
</children>
|
||||
<styles xmi:type="notation:ShapeStyle" xmi:id="_3-8Pc-v2EduQz8RnORu8xQ" fontColor="128" description="package java.io" fillColor="13369343" lineColor="10265827"/>
|
||||
<element xsi:nil="true"/>
|
||||
<layoutConstraint xmi:type="notation:Bounds" xmi:id="_3-8PdOv2EduQz8RnORu8xQ" x="24726" y="11729" height="793"/>
|
||||
</children>
|
||||
<styles xmi:type="umlnotation:UMLDiagramStyle" xmi:id="_zdRLcegOEdu5GYaBl4l5qw"/>
|
||||
<element xsi:nil="true"/>
|
||||
<edges xmi:id="_SKAcNugoEdu5GYaBl4l5qw" source="_kj8xUOgPEdu5GYaBl4l5qw" target="_SFOp4OgoEdu5GYaBl4l5qw">
|
||||
<children xmi:id="_SKAcOegoEdu5GYaBl4l5qw" type="NameLabel">
|
||||
<children xmi:id="_SKAcO-goEdu5GYaBl4l5qw" type="Stereotype"/>
|
||||
<children xmi:id="_SKAcPOgoEdu5GYaBl4l5qw" type="Name"/>
|
||||
<layoutConstraint xmi:type="notation:Bounds" xmi:id="_SKAcOugoEdu5GYaBl4l5qw" y="-186"/>
|
||||
</children>
|
||||
<styles xmi:type="umlnotation:UMLConnectorStyle" xmi:id="_SKAcN-goEdu5GYaBl4l5qw" showStereotype="Text"/>
|
||||
<element xmi:type="uml:Generalization" href="mmi:///#jgen%5Bjbintype%5Ename=com.thoughtworks.xstream.core.util.CustomObjectInputStream%5Bproject%5Eid=batch-breeze%5D%5D%5Bjbintype%5Ename=java.io.ObjectInputStream%5Bproject%5Eid=batch-breeze%5D%5D$uml.Generalization"/>
|
||||
<bendpoints xmi:type="notation:RelativeBendpoints" xmi:id="_SKAcOOgoEdu5GYaBl4l5qw" points="[0, 0, 0, 0]$[0, 0, 0, 0]"/>
|
||||
</edges>
|
||||
<edges xmi:id="_SKAcPegoEdu5GYaBl4l5qw" source="_SFOp4OgoEdu5GYaBl4l5qw" target="_Az2LA-gPEdu5GYaBl4l5qw">
|
||||
<children xmi:id="_SKAcQOgoEdu5GYaBl4l5qw" type="NameLabel">
|
||||
<children xmi:id="_SKAcQugoEdu5GYaBl4l5qw" type="Stereotype"/>
|
||||
<children xmi:id="_SKAcQ-goEdu5GYaBl4l5qw" type="Name"/>
|
||||
<layoutConstraint xmi:type="notation:Bounds" xmi:id="_SKAcQegoEdu5GYaBl4l5qw" y="-186"/>
|
||||
</children>
|
||||
<styles xmi:type="umlnotation:UMLConnectorStyle" xmi:id="_SKAcPugoEdu5GYaBl4l5qw" showStereotype="Text"/>
|
||||
<element xmi:type="uml:InterfaceRealization" href="mmi:///#jimpl%5Bjbintype%5Ename=java.io.ObjectInputStream%5Bproject%5Eid=batch-breeze%5D%5D%5Bjbintype%5Ename=java.io.ObjectInput%5Bproject%5Eid=batch-breeze%5D%5D$uml.InterfaceRealization"/>
|
||||
<bendpoints xmi:type="notation:RelativeBendpoints" xmi:id="_SKAcP-goEdu5GYaBl4l5qw" points="[-2143, 450, 3810, -767]$[-4312, 900, 1641, -317]"/>
|
||||
</edges>
|
||||
<edges xmi:id="_5umn0OgoEdu5GYaBl4l5qw" type="NoteAttachment" source="_kj8xUOgPEdu5GYaBl4l5qw" target="_5ughMOgoEdu5GYaBl4l5qw">
|
||||
<styles xmi:type="notation:ConnectorStyle" xmi:id="_5umn0egoEdu5GYaBl4l5qw"/>
|
||||
<element xsi:nil="true"/>
|
||||
<bendpoints xmi:type="notation:RelativeBendpoints" xmi:id="_5umn0ugoEdu5GYaBl4l5qw" points="[-27, -31, 292, 335]$[-319, -366, 0, 0]"/>
|
||||
</edges>
|
||||
<edges xmi:id="_zZ89cOgpEdu5GYaBl4l5qw" source="_sfqDoegPEdu5GYaBl4l5qw" target="_zY50kOgpEdu5GYaBl4l5qw">
|
||||
<children xmi:id="_zZ89c-gpEdu5GYaBl4l5qw" type="NameLabel">
|
||||
<children xmi:id="_zZ89degpEdu5GYaBl4l5qw" type="Stereotype"/>
|
||||
<children xmi:id="_zZ89dugpEdu5GYaBl4l5qw" type="Name"/>
|
||||
<layoutConstraint xmi:type="notation:Bounds" xmi:id="_zZ89dOgpEdu5GYaBl4l5qw" y="-186"/>
|
||||
</children>
|
||||
<styles xmi:type="umlnotation:UMLConnectorStyle" xmi:id="_zZ89cegpEdu5GYaBl4l5qw" showStereotype="Text"/>
|
||||
<element xmi:type="uml:Generalization" href="mmi:///#jgen%5Bjbintype%5Ename=com.thoughtworks.xstream.core.util.CustomObjectOutputStream%5Bproject%5Eid=batch-breeze%5D%5D%5Bjbintype%5Ename=java.io.ObjectOutputStream%5Bproject%5Eid=batch-breeze%5D%5D$uml.Generalization"/>
|
||||
<bendpoints xmi:type="notation:RelativeBendpoints" xmi:id="_zZ89cugpEdu5GYaBl4l5qw" points="[0, 0, 0, 0]$[0, 0, 0, 0]"/>
|
||||
</edges>
|
||||
<edges xmi:id="_zZ89d-gpEdu5GYaBl4l5qw" source="_zY50kOgpEdu5GYaBl4l5qw" target="_f0v4cOgpEdu5GYaBl4l5qw">
|
||||
<children xmi:id="_zZ89eugpEdu5GYaBl4l5qw" type="NameLabel">
|
||||
<children xmi:id="_zZ89fOgpEdu5GYaBl4l5qw" type="Stereotype"/>
|
||||
<children xmi:id="_zZ89fegpEdu5GYaBl4l5qw" type="Name"/>
|
||||
<layoutConstraint xmi:type="notation:Bounds" xmi:id="_zZ89e-gpEdu5GYaBl4l5qw" y="-186"/>
|
||||
</children>
|
||||
<styles xmi:type="umlnotation:UMLConnectorStyle" xmi:id="_zZ89eOgpEdu5GYaBl4l5qw" showStereotype="Text"/>
|
||||
<element xmi:type="uml:InterfaceRealization" href="mmi:///#jimpl%5Bjbintype%5Ename=java.io.ObjectOutputStream%5Bproject%5Eid=batch-breeze%5D%5D%5Bjbintype%5Ename=java.io.ObjectOutput%5Bproject%5Eid=batch-breeze%5D%5D$uml.InterfaceRealization"/>
|
||||
<bendpoints xmi:type="notation:RelativeBendpoints" xmi:id="_zZ89eegpEdu5GYaBl4l5qw" points="[0, 0, 0, 0]$[0, 0, 0, 0]"/>
|
||||
</edges>
|
||||
<edges xmi:id="_2TCqcOgpEdu5GYaBl4l5qw" type="NoteAttachment" source="_sfqDoegPEdu5GYaBl4l5qw" target="_2S8j0OgpEdu5GYaBl4l5qw">
|
||||
<styles xmi:type="notation:ConnectorStyle" xmi:id="_2TCqcegpEdu5GYaBl4l5qw"/>
|
||||
<element xsi:nil="true"/>
|
||||
<bendpoints xmi:type="notation:RelativeBendpoints" xmi:id="_2TCqcugpEdu5GYaBl4l5qw" points="[-73, -31, 766, 323]$[-839, -354, 0, 0]"/>
|
||||
</edges>
|
||||
<edges xmi:id="_2LMIcOhJEdu5GYaBl4l5qw" source="_3S6AQOgOEdu5GYaBl4l5qw" target="_2K50kOhJEdu5GYaBl4l5qw">
|
||||
<children xmi:id="_2LSPEOhJEdu5GYaBl4l5qw" type="KindLabel">
|
||||
<children xmi:id="_2LSPEuhJEdu5GYaBl4l5qw" type="Stereotype"/>
|
||||
<children xmi:id="_2LSPFOhJEdu5GYaBl4l5qw" type="Kind"/>
|
||||
<children xmi:id="_2LSPE-hJEdu5GYaBl4l5qw" type="Name"/>
|
||||
<layoutConstraint xmi:type="notation:Bounds" xmi:id="_2LSPEehJEdu5GYaBl4l5qw" y="-186"/>
|
||||
</children>
|
||||
<styles xmi:type="umlnotation:UMLConnectorStyle" xmi:id="_2LMIcehJEdu5GYaBl4l5qw" showStereotype="Text"/>
|
||||
<element xmi:type="uml:Usage" href="mmi:///#jdep%5Bjsrctype%5Ename=XmlInputTemplate%5Bjcu%5Ename=XmlInputTemplate.java%5Bjpack%5Ename=org.springframework.batch.container.io.file.xml.support%5Bjsrcroot%5Esrcfolder=src/main/java%5Bproject%5Eid=batch-breeze%5D%5D%5D%5D%5D%5Bjsrctype%5Ename=ObjectInput%5Bjcu%5Ename=ObjectInput.java%5Bjpack%5Ename=org.springframework.batch.container.io.file.xml.support%5Bjsrcroot%5Esrcfolder=src/main/java%5Bproject%5Eid=batch-breeze%5D%5D%5D%5D%5D$uml.Usage"/>
|
||||
<bendpoints xmi:type="notation:RelativeBendpoints" xmi:id="_2LMIcuhJEdu5GYaBl4l5qw" points="[0, 0, 0, 0]$[0, 0, 0, 0]"/>
|
||||
</edges>
|
||||
<edges xmi:id="_2cxAoOhJEdu5GYaBl4l5qw" source="_6ojGYOgOEdu5GYaBl4l5qw" target="_2cYmIOhJEdu5GYaBl4l5qw">
|
||||
<children xmi:id="_2c3HQOhJEdu5GYaBl4l5qw" type="KindLabel">
|
||||
<children xmi:id="_2c3HQuhJEdu5GYaBl4l5qw" type="Stereotype"/>
|
||||
<children xmi:id="_2c3HROhJEdu5GYaBl4l5qw" type="Kind"/>
|
||||
<children xmi:id="_2c3HQ-hJEdu5GYaBl4l5qw" type="Name"/>
|
||||
<layoutConstraint xmi:type="notation:Bounds" xmi:id="_2c3HQehJEdu5GYaBl4l5qw" y="-186"/>
|
||||
</children>
|
||||
<styles xmi:type="umlnotation:UMLConnectorStyle" xmi:id="_2cxAoehJEdu5GYaBl4l5qw" showStereotype="Text"/>
|
||||
<element xmi:type="uml:Usage" href="mmi:///#jdep%5Bjsrctype%5Ename=XmlOutputTemplate%5Bjcu%5Ename=XmlOutputTemplate.java%5Bjpack%5Ename=org.springframework.batch.container.io.file.xml.support%5Bjsrcroot%5Esrcfolder=src/main/java%5Bproject%5Eid=batch-breeze%5D%5D%5D%5D%5D%5Bjsrctype%5Ename=ObjectOutput%5Bjcu%5Ename=ObjectOutput.java%5Bjpack%5Ename=org.springframework.batch.container.io.file.xml.support%5Bjsrcroot%5Esrcfolder=src/main/java%5Bproject%5Eid=batch-breeze%5D%5D%5D%5D%5D$uml.Usage"/>
|
||||
<bendpoints xmi:type="notation:RelativeBendpoints" xmi:id="_2cxAouhJEdu5GYaBl4l5qw" points="[0, 0, 0, 0]$[0, 0, 0, 0]"/>
|
||||
</edges>
|
||||
<edges xmi:id="_6E16kOhJEdu5GYaBl4l5qw" source="_3S6AQOgOEdu5GYaBl4l5qw" target="_6EjmsOhJEdu5GYaBl4l5qw">
|
||||
<children xmi:id="_6E16k-hJEdu5GYaBl4l5qw" type="KindLabel">
|
||||
<children xmi:id="_6E16lehJEdu5GYaBl4l5qw" type="Stereotype"/>
|
||||
<children xmi:id="_6E16l-hJEdu5GYaBl4l5qw" type="Kind"/>
|
||||
<children xmi:id="_6E16luhJEdu5GYaBl4l5qw" type="Name"/>
|
||||
<layoutConstraint xmi:type="notation:Bounds" xmi:id="_6E16lOhJEdu5GYaBl4l5qw" y="-186"/>
|
||||
</children>
|
||||
<styles xmi:type="umlnotation:UMLConnectorStyle" xmi:id="_6E16kehJEdu5GYaBl4l5qw" showStereotype="Text"/>
|
||||
<element xmi:type="uml:Usage" href="mmi:///#jdep%5Bjsrctype%5Ename=XmlInputTemplate%5Bjcu%5Ename=XmlInputTemplate.java%5Bjpack%5Ename=org.springframework.batch.container.io.file.xml.support%5Bjsrcroot%5Esrcfolder=src/main/java%5Bproject%5Eid=batch-breeze%5D%5D%5D%5D%5D%5Bjsrctype%5Ename=ObjectInputFactory%5Bjcu%5Ename=ObjectInputFactory.java%5Bjpack%5Ename=org.springframework.batch.container.io.file.xml.support%5Bjsrcroot%5Esrcfolder=src/main/java%5Bproject%5Eid=batch-breeze%5D%5D%5D%5D%5D$uml.Usage"/>
|
||||
<bendpoints xmi:type="notation:RelativeBendpoints" xmi:id="_6E16kuhJEdu5GYaBl4l5qw" points="[0, 0, 0, 0]$[0, 0, 0, 0]"/>
|
||||
</edges>
|
||||
<edges xmi:id="_6E16n-hJEdu5GYaBl4l5qw" source="_6EjmsOhJEdu5GYaBl4l5qw" target="_2K50kOhJEdu5GYaBl4l5qw">
|
||||
<children xmi:id="_6E16ouhJEdu5GYaBl4l5qw" type="KindLabel">
|
||||
<children xmi:id="_6E8BMOhJEdu5GYaBl4l5qw" type="Stereotype"/>
|
||||
<children xmi:id="_6E8BMuhJEdu5GYaBl4l5qw" type="Kind"/>
|
||||
<children xmi:id="_6E8BMehJEdu5GYaBl4l5qw" type="Name"/>
|
||||
<layoutConstraint xmi:type="notation:Bounds" xmi:id="_6E16o-hJEdu5GYaBl4l5qw" y="-186"/>
|
||||
</children>
|
||||
<styles xmi:type="umlnotation:UMLConnectorStyle" xmi:id="_6E16oOhJEdu5GYaBl4l5qw" showStereotype="Text"/>
|
||||
<element xmi:type="uml:Usage" href="mmi:///#jdep%5Bjsrctype%5Ename=ObjectInputFactory%5Bjcu%5Ename=ObjectInputFactory.java%5Bjpack%5Ename=org.springframework.batch.container.io.file.xml.support%5Bjsrcroot%5Esrcfolder=src/main/java%5Bproject%5Eid=batch-breeze%5D%5D%5D%5D%5D%5Bjsrctype%5Ename=ObjectInput%5Bjcu%5Ename=ObjectInput.java%5Bjpack%5Ename=org.springframework.batch.container.io.file.xml.support%5Bjsrcroot%5Esrcfolder=src/main/java%5Bproject%5Eid=batch-breeze%5D%5D%5D%5D%5D$uml.Usage"/>
|
||||
<bendpoints xmi:type="notation:RelativeBendpoints" xmi:id="_6E16oehJEdu5GYaBl4l5qw" points="[0, 0, 0, 0]$[0, 0, 0, 0]"/>
|
||||
</edges>
|
||||
<edges xmi:id="_9t32wOhJEdu5GYaBl4l5qw" source="_6ojGYOgOEdu5GYaBl4l5qw" target="_9tli4OhJEdu5GYaBl4l5qw">
|
||||
<children xmi:id="_9t32w-hJEdu5GYaBl4l5qw" type="KindLabel">
|
||||
<children xmi:id="_9t32xehJEdu5GYaBl4l5qw" type="Stereotype"/>
|
||||
<children xmi:id="_9t32x-hJEdu5GYaBl4l5qw" type="Kind"/>
|
||||
<children xmi:id="_9t32xuhJEdu5GYaBl4l5qw" type="Name"/>
|
||||
<layoutConstraint xmi:type="notation:Bounds" xmi:id="_9t32xOhJEdu5GYaBl4l5qw" y="-186"/>
|
||||
</children>
|
||||
<styles xmi:type="umlnotation:UMLConnectorStyle" xmi:id="_9t32wehJEdu5GYaBl4l5qw" showStereotype="Text"/>
|
||||
<element xmi:type="uml:Usage" href="mmi:///#jdep%5Bjsrctype%5Ename=XmlOutputTemplate%5Bjcu%5Ename=XmlOutputTemplate.java%5Bjpack%5Ename=org.springframework.batch.container.io.file.xml.support%5Bjsrcroot%5Esrcfolder=src/main/java%5Bproject%5Eid=batch-breeze%5D%5D%5D%5D%5D%5Bjsrctype%5Ename=ObjectOutputFactory%5Bjcu%5Ename=ObjectOutputFactory.java%5Bjpack%5Ename=org.springframework.batch.container.io.file.xml.support%5Bjsrcroot%5Esrcfolder=src/main/java%5Bproject%5Eid=batch-breeze%5D%5D%5D%5D%5D$uml.Usage"/>
|
||||
<bendpoints xmi:type="notation:RelativeBendpoints" xmi:id="_9t32wuhJEdu5GYaBl4l5qw" points="[0, 0, 0, 0]$[0, 0, 0, 0]"/>
|
||||
</edges>
|
||||
<edges xmi:id="_9t99YOhJEdu5GYaBl4l5qw" source="_9tli4OhJEdu5GYaBl4l5qw" target="_2cYmIOhJEdu5GYaBl4l5qw">
|
||||
<children xmi:id="_9t99Y-hJEdu5GYaBl4l5qw" type="KindLabel">
|
||||
<children xmi:id="_9t99ZehJEdu5GYaBl4l5qw" type="Stereotype"/>
|
||||
<children xmi:id="_9t99Z-hJEdu5GYaBl4l5qw" type="Kind"/>
|
||||
<children xmi:id="_9t99ZuhJEdu5GYaBl4l5qw" type="Name"/>
|
||||
<layoutConstraint xmi:type="notation:Bounds" xmi:id="_9t99ZOhJEdu5GYaBl4l5qw" y="-186"/>
|
||||
</children>
|
||||
<styles xmi:type="umlnotation:UMLConnectorStyle" xmi:id="_9t99YehJEdu5GYaBl4l5qw" showStereotype="Text"/>
|
||||
<element xmi:type="uml:Usage" href="mmi:///#jdep%5Bjsrctype%5Ename=ObjectOutputFactory%5Bjcu%5Ename=ObjectOutputFactory.java%5Bjpack%5Ename=org.springframework.batch.container.io.file.xml.support%5Bjsrcroot%5Esrcfolder=src/main/java%5Bproject%5Eid=batch-breeze%5D%5D%5D%5D%5D%5Bjsrctype%5Ename=ObjectOutput%5Bjcu%5Ename=ObjectOutput.java%5Bjpack%5Ename=org.springframework.batch.container.io.file.xml.support%5Bjsrcroot%5Esrcfolder=src/main/java%5Bproject%5Eid=batch-breeze%5D%5D%5D%5D%5D$uml.Usage"/>
|
||||
<bendpoints xmi:type="notation:RelativeBendpoints" xmi:id="_9t99YuhJEdu5GYaBl4l5qw" points="[0, 0, 0, 0]$[0, 0, 0, 0]"/>
|
||||
</edges>
|
||||
<edges xmi:id="_Ka_poOhKEdu5GYaBl4l5qw" type="OwnedElement" source="_KaIuGOhKEdu5GYaBl4l5qw" target="_KaIuAOhKEdu5GYaBl4l5qw">
|
||||
<styles xmi:type="umlnotation:UMLConnectorStyle" xmi:id="_Ka_poehKEdu5GYaBl4l5qw" showStereotype="Text"/>
|
||||
<element xsi:nil="true"/>
|
||||
<bendpoints xmi:type="notation:RelativeBendpoints" xmi:id="_Ka_pouhKEdu5GYaBl4l5qw" points="[0, 4366, 3201, -4683]$[-3201, 5953, 0, -3096]"/>
|
||||
</edges>
|
||||
<edges xmi:id="_Ka_po-hKEdu5GYaBl4l5qw" source="_KaIuAOhKEdu5GYaBl4l5qw" target="_Az2LA-gPEdu5GYaBl4l5qw">
|
||||
<children xmi:id="_Ka_ppuhKEdu5GYaBl4l5qw" type="KindLabel">
|
||||
<children xmi:id="_Ka_pqOhKEdu5GYaBl4l5qw" type="Stereotype"/>
|
||||
<children xmi:id="_Ka_pquhKEdu5GYaBl4l5qw" type="Kind"/>
|
||||
<children xmi:id="_Ka_pqehKEdu5GYaBl4l5qw" type="Name"/>
|
||||
<layoutConstraint xmi:type="notation:Bounds" xmi:id="_Ka_pp-hKEdu5GYaBl4l5qw" y="-186"/>
|
||||
</children>
|
||||
<styles xmi:type="umlnotation:UMLConnectorStyle" xmi:id="_Ka_ppOhKEdu5GYaBl4l5qw" showStereotype="Text"/>
|
||||
<element xmi:type="uml:Usage" href="mmi:///#jdep%5Bjsrctype%5Ename=ObjectInputWrapper%5Bjsrctype%5Ename=XStreamFactory%5Bjcu%5Ename=XStreamFactory.java%5Bjpack%5Ename=org.springframework.batch.container.io.file.xml.support%5Bjsrcroot%5Esrcfolder=src/main/java%5Bproject%5Eid=batch-breeze%5D%5D%5D%5D%5D%5D%5Bjbintype%5Ename=java.io.ObjectInput%5Bproject%5Eid=batch-breeze%5D%5D$uml.Usage"/>
|
||||
<bendpoints xmi:type="notation:RelativeBendpoints" xmi:id="_Ka_ppehKEdu5GYaBl4l5qw" points="[0, 0, 0, 0]$[0, 0, 0, 0]"/>
|
||||
</edges>
|
||||
<edges xmi:id="_Ka_ps-hKEdu5GYaBl4l5qw" source="_KaIuAOhKEdu5GYaBl4l5qw" target="_2K50kOhJEdu5GYaBl4l5qw">
|
||||
<children xmi:id="_Ka_ptuhKEdu5GYaBl4l5qw" type="NameLabel">
|
||||
<children xmi:id="_Ka_puOhKEdu5GYaBl4l5qw" type="Stereotype"/>
|
||||
<children xmi:id="_Ka_puehKEdu5GYaBl4l5qw" type="Name"/>
|
||||
<layoutConstraint xmi:type="notation:Bounds" xmi:id="_Ka_pt-hKEdu5GYaBl4l5qw" y="-186"/>
|
||||
</children>
|
||||
<styles xmi:type="umlnotation:UMLConnectorStyle" xmi:id="_Ka_ptOhKEdu5GYaBl4l5qw" showStereotype="Text"/>
|
||||
<element xmi:type="uml:InterfaceRealization" href="mmi:///#jimpl%5Bjsrctype%5Ename=ObjectInputWrapper%5Bjsrctype%5Ename=XStreamFactory%5Bjcu%5Ename=XStreamFactory.java%5Bjpack%5Ename=org.springframework.batch.container.io.file.xml.support%5Bjsrcroot%5Esrcfolder=src/main/java%5Bproject%5Eid=batch-breeze%5D%5D%5D%5D%5D%5D%5Bjsrctype%5Ename=ObjectInput%5Bjcu%5Ename=ObjectInput.java%5Bjpack%5Ename=org.springframework.batch.container.io.file.xml.support%5Bjsrcroot%5Esrcfolder=src/main/java%5Bproject%5Eid=batch-breeze%5D%5D%5D%5D%5D$uml.InterfaceRealization"/>
|
||||
<bendpoints xmi:type="notation:RelativeBendpoints" xmi:id="_Ka_ptehKEdu5GYaBl4l5qw" points="[0, 0, 0, 0]$[0, 0, 0, 0]"/>
|
||||
</edges>
|
||||
<edges xmi:id="_Ka_puuhKEdu5GYaBl4l5qw" type="OwnedElement" source="_KaIuGOhKEdu5GYaBl4l5qw" target="_KaIuDOhKEdu5GYaBl4l5qw">
|
||||
<styles xmi:type="umlnotation:UMLConnectorStyle" xmi:id="_Ka_pu-hKEdu5GYaBl4l5qw" showStereotype="Text"/>
|
||||
<element xsi:nil="true"/>
|
||||
<bendpoints xmi:type="notation:RelativeBendpoints" xmi:id="_Ka_pvOhKEdu5GYaBl4l5qw" points="[0, 4366, -3228, -4683]$[3228, 5953, 0, -3096]"/>
|
||||
</edges>
|
||||
<edges xmi:id="_KbFwSOhKEdu5GYaBl4l5qw" source="_KaIuDOhKEdu5GYaBl4l5qw" target="_2cYmIOhJEdu5GYaBl4l5qw">
|
||||
<children xmi:id="_KbFwS-hKEdu5GYaBl4l5qw" type="NameLabel">
|
||||
<children xmi:id="_KbFwTehKEdu5GYaBl4l5qw" type="Stereotype"/>
|
||||
<children xmi:id="_KbL24OhKEdu5GYaBl4l5qw" type="Name"/>
|
||||
<layoutConstraint xmi:type="notation:Bounds" xmi:id="_KbFwTOhKEdu5GYaBl4l5qw" y="-186"/>
|
||||
</children>
|
||||
<styles xmi:type="umlnotation:UMLConnectorStyle" xmi:id="_KbFwSehKEdu5GYaBl4l5qw" showStereotype="Text"/>
|
||||
<element xmi:type="uml:InterfaceRealization" href="mmi:///#jimpl%5Bjsrctype%5Ename=ObjectOutputWrapper%5Bjsrctype%5Ename=XStreamFactory%5Bjcu%5Ename=XStreamFactory.java%5Bjpack%5Ename=org.springframework.batch.container.io.file.xml.support%5Bjsrcroot%5Esrcfolder=src/main/java%5Bproject%5Eid=batch-breeze%5D%5D%5D%5D%5D%5D%5Bjsrctype%5Ename=ObjectOutput%5Bjcu%5Ename=ObjectOutput.java%5Bjpack%5Ename=org.springframework.batch.container.io.file.xml.support%5Bjsrcroot%5Esrcfolder=src/main/java%5Bproject%5Eid=batch-breeze%5D%5D%5D%5D%5D$uml.InterfaceRealization"/>
|
||||
<bendpoints xmi:type="notation:RelativeBendpoints" xmi:id="_KbFwSuhKEdu5GYaBl4l5qw" points="[0, 0, 0, 0]$[0, 0, 0, 0]"/>
|
||||
</edges>
|
||||
<edges xmi:id="_KbL24ehKEdu5GYaBl4l5qw" source="_KaIuDOhKEdu5GYaBl4l5qw" target="_f0v4cOgpEdu5GYaBl4l5qw">
|
||||
<children xmi:id="_KbL25OhKEdu5GYaBl4l5qw" type="KindLabel">
|
||||
<children xmi:id="_KbL25uhKEdu5GYaBl4l5qw" type="Stereotype"/>
|
||||
<children xmi:id="_KbL26OhKEdu5GYaBl4l5qw" type="Kind"/>
|
||||
<children xmi:id="_KbL25-hKEdu5GYaBl4l5qw" type="Name"/>
|
||||
<layoutConstraint xmi:type="notation:Bounds" xmi:id="_KbL25ehKEdu5GYaBl4l5qw" y="-186"/>
|
||||
</children>
|
||||
<styles xmi:type="umlnotation:UMLConnectorStyle" xmi:id="_KbL24uhKEdu5GYaBl4l5qw" showStereotype="Text"/>
|
||||
<element xmi:type="uml:Usage" href="mmi:///#jdep%5Bjsrctype%5Ename=ObjectOutputWrapper%5Bjsrctype%5Ename=XStreamFactory%5Bjcu%5Ename=XStreamFactory.java%5Bjpack%5Ename=org.springframework.batch.container.io.file.xml.support%5Bjsrcroot%5Esrcfolder=src/main/java%5Bproject%5Eid=batch-breeze%5D%5D%5D%5D%5D%5D%5Bjbintype%5Ename=java.io.ObjectOutput%5Bproject%5Eid=batch-breeze%5D%5D$uml.Usage"/>
|
||||
<bendpoints xmi:type="notation:RelativeBendpoints" xmi:id="_KbL24-hKEdu5GYaBl4l5qw" points="[0, 0, 0, 0]$[0, 0, 0, 0]"/>
|
||||
</edges>
|
||||
<edges xmi:id="_KbR9g-hKEdu5GYaBl4l5qw" source="_KaIuGOhKEdu5GYaBl4l5qw" target="_9tli4OhJEdu5GYaBl4l5qw">
|
||||
<children xmi:id="_KbR9huhKEdu5GYaBl4l5qw" type="NameLabel">
|
||||
<children xmi:id="_KbR9iOhKEdu5GYaBl4l5qw" type="Stereotype"/>
|
||||
<children xmi:id="_KbR9iehKEdu5GYaBl4l5qw" type="Name"/>
|
||||
<layoutConstraint xmi:type="notation:Bounds" xmi:id="_KbR9h-hKEdu5GYaBl4l5qw" y="-186"/>
|
||||
</children>
|
||||
<styles xmi:type="umlnotation:UMLConnectorStyle" xmi:id="_KbR9hOhKEdu5GYaBl4l5qw" showStereotype="Text"/>
|
||||
<element xmi:type="uml:InterfaceRealization" href="mmi:///#jimpl%5Bjsrctype%5Ename=XStreamFactory%5Bjcu%5Ename=XStreamFactory.java%5Bjpack%5Ename=org.springframework.batch.container.io.file.xml.support%5Bjsrcroot%5Esrcfolder=src/main/java%5Bproject%5Eid=batch-breeze%5D%5D%5D%5D%5D%5Bjsrctype%5Ename=ObjectOutputFactory%5Bjcu%5Ename=ObjectOutputFactory.java%5Bjpack%5Ename=org.springframework.batch.container.io.file.xml.support%5Bjsrcroot%5Esrcfolder=src/main/java%5Bproject%5Eid=batch-breeze%5D%5D%5D%5D%5D$uml.InterfaceRealization"/>
|
||||
<bendpoints xmi:type="notation:RelativeBendpoints" xmi:id="_KbR9hehKEdu5GYaBl4l5qw" points="[0, 0, 0, 0]$[0, 0, 0, 0]"/>
|
||||
</edges>
|
||||
<edges xmi:id="_KbR9iuhKEdu5GYaBl4l5qw" source="_KaIuGOhKEdu5GYaBl4l5qw" target="_6EjmsOhJEdu5GYaBl4l5qw">
|
||||
<children xmi:id="_KbR9jehKEdu5GYaBl4l5qw" type="NameLabel">
|
||||
<children xmi:id="_KbR9j-hKEdu5GYaBl4l5qw" type="Stereotype"/>
|
||||
<children xmi:id="_KbR9kOhKEdu5GYaBl4l5qw" type="Name"/>
|
||||
<layoutConstraint xmi:type="notation:Bounds" xmi:id="_KbR9juhKEdu5GYaBl4l5qw" y="-186"/>
|
||||
</children>
|
||||
<styles xmi:type="umlnotation:UMLConnectorStyle" xmi:id="_KbR9i-hKEdu5GYaBl4l5qw" showStereotype="Text"/>
|
||||
<element xmi:type="uml:InterfaceRealization" href="mmi:///#jimpl%5Bjsrctype%5Ename=XStreamFactory%5Bjcu%5Ename=XStreamFactory.java%5Bjpack%5Ename=org.springframework.batch.container.io.file.xml.support%5Bjsrcroot%5Esrcfolder=src/main/java%5Bproject%5Eid=batch-breeze%5D%5D%5D%5D%5D%5Bjsrctype%5Ename=ObjectInputFactory%5Bjcu%5Ename=ObjectInputFactory.java%5Bjpack%5Ename=org.springframework.batch.container.io.file.xml.support%5Bjsrcroot%5Esrcfolder=src/main/java%5Bproject%5Eid=batch-breeze%5D%5D%5D%5D%5D$uml.InterfaceRealization"/>
|
||||
<bendpoints xmi:type="notation:RelativeBendpoints" xmi:id="_KbR9jOhKEdu5GYaBl4l5qw" points="[0, 0, 0, 0]$[0, 0, 0, 0]"/>
|
||||
</edges>
|
||||
<edges xmi:id="_KbYENehKEdu5GYaBl4l5qw" source="_KaIuGOhKEdu5GYaBl4l5qw" target="_DdzUMOgtEdu5GYaBl4l5qw">
|
||||
<children xmi:id="_KbYEOOhKEdu5GYaBl4l5qw" type="KindLabel">
|
||||
<children xmi:id="_KbYEOuhKEdu5GYaBl4l5qw" type="Stereotype"/>
|
||||
<children xmi:id="_KbYEPOhKEdu5GYaBl4l5qw" type="Kind"/>
|
||||
<children xmi:id="_KbYEO-hKEdu5GYaBl4l5qw" type="Name"/>
|
||||
<layoutConstraint xmi:type="notation:Bounds" xmi:id="_KbYEOehKEdu5GYaBl4l5qw" y="-186"/>
|
||||
</children>
|
||||
<styles xmi:type="umlnotation:UMLConnectorStyle" xmi:id="_KbYENuhKEdu5GYaBl4l5qw" showStereotype="Text"/>
|
||||
<element xmi:type="uml:Usage" href="mmi:///#jdep%5Bjsrctype%5Ename=XStreamFactory%5Bjcu%5Ename=XStreamFactory.java%5Bjpack%5Ename=org.springframework.batch.container.io.file.xml.support%5Bjsrcroot%5Esrcfolder=src/main/java%5Bproject%5Eid=batch-breeze%5D%5D%5D%5D%5D%5Bjsrctype%5Ename=XStreamConfiguration%5Bjcu%5Ename=XStreamConfiguration.java%5Bjpack%5Ename=org.springframework.batch.container.io.file.xml.support%5Bjsrcroot%5Esrcfolder=src/main/java%5Bproject%5Eid=batch-breeze%5D%5D%5D%5D%5D$uml.Usage"/>
|
||||
<bendpoints xmi:type="notation:RelativeBendpoints" xmi:id="_KbYEN-hKEdu5GYaBl4l5qw" points="[0, 0, 0, 0]$[0, 0, 0, 0]"/>
|
||||
</edges>
|
||||
<edges xmi:id="_PFqY0OjVEduS0q4MIMV9Cw" source="_PFLQoOjVEduS0q4MIMV9Cw" target="_DdzUMOgtEdu5GYaBl4l5qw">
|
||||
<children xmi:id="_PFqY0-jVEduS0q4MIMV9Cw" type="KindLabel">
|
||||
<children xmi:id="_PFqY1ejVEduS0q4MIMV9Cw" type="Stereotype"/>
|
||||
<children xmi:id="_PFqY1-jVEduS0q4MIMV9Cw" type="Kind"/>
|
||||
<children xmi:id="_PFqY1ujVEduS0q4MIMV9Cw" type="Name"/>
|
||||
<layoutConstraint xmi:type="notation:Bounds" xmi:id="_PFqY1OjVEduS0q4MIMV9Cw" y="-186"/>
|
||||
</children>
|
||||
<styles xmi:type="umlnotation:UMLConnectorStyle" xmi:id="_PFqY0ejVEduS0q4MIMV9Cw" showStereotype="Text"/>
|
||||
<element xmi:type="uml:Usage" href="mmi:///#jdep%5Bjsrctype%5Ename=XStreamConfigurationFactory%5Bjcu%5Ename=XStreamConfigurationFactory.java%5Bjpack%5Ename=org.springframework.batch.container.io.file.xml.support%5Bjsrcroot%5Esrcfolder=src/main/java%5Bproject%5Eid=batch-breeze%5D%5D%5D%5D%5D%5Bjsrctype%5Ename=XStreamConfiguration%5Bjcu%5Ename=XStreamConfiguration.java%5Bjpack%5Ename=org.springframework.batch.container.io.file.xml.support%5Bjsrcroot%5Esrcfolder=src/main/java%5Bproject%5Eid=batch-breeze%5D%5D%5D%5D%5D$uml.Usage"/>
|
||||
<bendpoints xmi:type="notation:RelativeBendpoints" xmi:id="_PFqY0ujVEduS0q4MIMV9Cw" points="[0, 0, 0, 0]$[0, 0, 0, 0]"/>
|
||||
</edges>
|
||||
<edges xmi:id="_zPzm0Ov2EduQz8RnORu8xQ" type="NoteAttachment" source="_Az2LA-gPEdu5GYaBl4l5qw" target="_zKpaAOv2EduQz8RnORu8xQ">
|
||||
<styles xmi:type="notation:ConnectorStyle" xmi:id="_zPzm0ev2EduQz8RnORu8xQ"/>
|
||||
<element xsi:nil="true"/>
|
||||
<bendpoints xmi:type="notation:RelativeBendpoints" xmi:id="_zPzm0uv2EduQz8RnORu8xQ" points="[-16, -81, 102, 503]$[-118, -584, 0, 0]"/>
|
||||
</edges>
|
||||
<edges xmi:id="_5L6Y4Ov2EduQz8RnORu8xQ" type="NoteAttachment" source="_3-8PcOv2EduQz8RnORu8xQ" target="_f0v4cOgpEdu5GYaBl4l5qw">
|
||||
<styles xmi:type="notation:ConnectorStyle" xmi:id="_5L6Y4ev2EduQz8RnORu8xQ"/>
|
||||
<element xsi:nil="true"/>
|
||||
<bendpoints xmi:type="notation:RelativeBendpoints" xmi:id="_5L6Y4uv2EduQz8RnORu8xQ" points="[0, 0, -7, -114]$[0, 41, -7, -73]"/>
|
||||
<sourceAnchor xmi:type="notation:IdentityAnchor" xmi:id="_5MAfgOv2EduQz8RnORu8xQ" id="(0.43587843,1.0)"/>
|
||||
</edges>
|
||||
</notation:Diagram>
|
||||
@@ -1,7 +0,0 @@
|
||||
<html>
|
||||
<body>
|
||||
<p>
|
||||
Infrastructure implementations of io xml xstream concerns.
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,167 +0,0 @@
|
||||
/*
|
||||
* 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.io.xml;
|
||||
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.io.ObjectInput;
|
||||
|
||||
import javax.xml.stream.Location;
|
||||
import javax.xml.stream.XMLStreamException;
|
||||
import javax.xml.stream.XMLStreamReader;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.easymock.MockControl;
|
||||
import org.springframework.batch.io.xml.xstream.XStreamFactory.ObjectInputWrapper;
|
||||
import org.springframework.dao.DataAccessResourceFailureException;
|
||||
|
||||
/**
|
||||
* Unit tests for {@link ObjectInputWrapper}.
|
||||
* @author peter.zozom
|
||||
*/
|
||||
public class ObjectInputWrapperTests extends TestCase {
|
||||
|
||||
private ObjectInputWrapper wrapper;
|
||||
|
||||
private MockControl readerControl;
|
||||
|
||||
private XMLStreamReader reader;
|
||||
|
||||
private MockControl oiControl;
|
||||
|
||||
private ObjectInput input;
|
||||
|
||||
public void setUp() throws FileNotFoundException, XMLStreamException {
|
||||
|
||||
// create mock reader
|
||||
readerControl = MockControl.createControl(XMLStreamReader.class);
|
||||
reader = (XMLStreamReader) readerControl.getMock();
|
||||
|
||||
// create mock for java.io.ObjectInput
|
||||
oiControl = MockControl.createControl(ObjectInput.class);
|
||||
input = (ObjectInput) oiControl.getMock();
|
||||
|
||||
// create ObjectInputWrapper
|
||||
wrapper = new ObjectInputWrapper(reader, input);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test {@link ObjectInputWrapper#position()}.
|
||||
*/
|
||||
public void testPosition() {
|
||||
|
||||
// create mock for Location
|
||||
MockControl locationControl = MockControl.createControl(Location.class);
|
||||
Location location = (Location) locationControl.getMock();
|
||||
location.getLineNumber();
|
||||
locationControl.setReturnValue(104);
|
||||
locationControl.replay();
|
||||
|
||||
// set up reader mock
|
||||
reader.getLocation();
|
||||
readerControl.setReturnValue(location);
|
||||
readerControl.replay();
|
||||
|
||||
assertEquals(104, wrapper.position());
|
||||
|
||||
readerControl.verify();
|
||||
locationControl.verify();
|
||||
}
|
||||
|
||||
/**
|
||||
* Test {@link ObjectInputWrapper#readObject()}
|
||||
* @throws ClassNotFoundException
|
||||
* @throws IOException
|
||||
*/
|
||||
public void testReadObject() throws ClassNotFoundException, IOException {
|
||||
|
||||
// set up objectInput mock
|
||||
input.readObject();
|
||||
oiControl.setReturnValue(this);
|
||||
oiControl.replay();
|
||||
|
||||
// read object
|
||||
assertSame(this, wrapper.readObject());
|
||||
|
||||
oiControl.verify();
|
||||
}
|
||||
|
||||
public void testClose() throws XMLStreamException, IOException {
|
||||
|
||||
// TEST CLOSE
|
||||
|
||||
// set up reader mock
|
||||
reader.close();
|
||||
readerControl.replay();
|
||||
|
||||
// set up objectInput mock
|
||||
input.close();
|
||||
oiControl.replay();
|
||||
|
||||
wrapper.close();
|
||||
|
||||
readerControl.verify();
|
||||
oiControl.verify();
|
||||
|
||||
// TEST CLOSE WITH XMLStreamException
|
||||
|
||||
// set up reader mock
|
||||
readerControl.reset();
|
||||
reader.close();
|
||||
readerControl.setThrowable(new XMLStreamException());
|
||||
readerControl.replay();
|
||||
|
||||
// set up objectInput mock
|
||||
oiControl.reset();
|
||||
input.close();
|
||||
oiControl.replay();
|
||||
|
||||
try {
|
||||
wrapper.close();
|
||||
fail("BatchCriticalException was expected");
|
||||
}
|
||||
catch (DataAccessResourceFailureException darfe) {
|
||||
assertTrue(darfe.getCause() instanceof XMLStreamException);
|
||||
}
|
||||
|
||||
readerControl.verify();
|
||||
oiControl.verify();
|
||||
|
||||
// TEST CLOSE WITH IOException
|
||||
// set up reader mock
|
||||
readerControl.reset();
|
||||
readerControl.replay();
|
||||
|
||||
// set up objectInput mock
|
||||
oiControl.reset();
|
||||
input.close();
|
||||
oiControl.setThrowable(new IOException());
|
||||
oiControl.replay();
|
||||
|
||||
try {
|
||||
wrapper.close();
|
||||
fail("BatchCriticalException was expected");
|
||||
}
|
||||
catch (DataAccessResourceFailureException darfe) {
|
||||
assertTrue(darfe.getCause() instanceof IOException);
|
||||
}
|
||||
|
||||
readerControl.verify();
|
||||
oiControl.verify();
|
||||
}
|
||||
}
|
||||
@@ -1,398 +0,0 @@
|
||||
/*
|
||||
* 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.io.xml;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.ObjectOutput;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.MappedByteBuffer;
|
||||
import java.nio.channels.FileChannel;
|
||||
import java.nio.channels.FileLock;
|
||||
import java.nio.channels.ReadableByteChannel;
|
||||
import java.nio.channels.WritableByteChannel;
|
||||
|
||||
import javax.xml.stream.XMLStreamException;
|
||||
import javax.xml.stream.XMLStreamWriter;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.easymock.MockControl;
|
||||
import org.springframework.batch.io.xml.xstream.XStreamFactory.ObjectOutputWrapper;
|
||||
import org.springframework.dao.DataAccessResourceFailureException;
|
||||
|
||||
/**
|
||||
* Unit tests for {@link ObjectOutputWrapper}.
|
||||
* @author peter.zozom
|
||||
*/
|
||||
public class ObjectOutputWrapperTests extends TestCase {
|
||||
|
||||
private ObjectOutputWrapper wrapper;
|
||||
|
||||
private MockControl writerControl;
|
||||
|
||||
private XMLStreamWriter writer;
|
||||
|
||||
private MockControl ooControl;
|
||||
|
||||
private ObjectOutput output;
|
||||
|
||||
private MockFileChannel channel;
|
||||
|
||||
public void setUp() {
|
||||
|
||||
// create mock for xml writer
|
||||
writerControl = MockControl.createControl(XMLStreamWriter.class);
|
||||
writer = (XMLStreamWriter) writerControl.getMock();
|
||||
|
||||
// create mock for java.io.objectOutput
|
||||
ooControl = MockControl.createControl(ObjectOutput.class);
|
||||
output = (ObjectOutput) ooControl.getMock();
|
||||
|
||||
// create mock for file channel
|
||||
channel = new MockFileChannel();
|
||||
|
||||
// create wrapper
|
||||
wrapper = new ObjectOutputWrapper(writer, channel, output);
|
||||
}
|
||||
|
||||
public void testAfterRestart() throws XMLStreamException, IOException {
|
||||
|
||||
// set up writer mock
|
||||
writer.writeComment("");
|
||||
writerControl.replay();
|
||||
|
||||
// set up objectOutput mock
|
||||
output.flush();
|
||||
ooControl.replay();
|
||||
|
||||
// call after restart
|
||||
wrapper.afterRestart(new Long(99));
|
||||
|
||||
// check size and position
|
||||
assertEquals(99, channel.size());
|
||||
assertEquals(99, channel.position());
|
||||
|
||||
// TEST EXCEPTION HANDLING
|
||||
|
||||
// set up writer mock
|
||||
writerControl.reset();
|
||||
writer.writeComment("");
|
||||
writerControl.setThrowable(new XMLStreamException());
|
||||
writerControl.replay();
|
||||
|
||||
try {
|
||||
wrapper.afterRestart(new Long(74));
|
||||
fail("BatchCriticalException was expected");
|
||||
}
|
||||
catch (DataAccessResourceFailureException bce) {
|
||||
assertTrue(bce.getCause() instanceof XMLStreamException);
|
||||
}
|
||||
|
||||
// set up writer mock
|
||||
writerControl.reset();
|
||||
writer.writeComment("");
|
||||
writerControl.replay();
|
||||
|
||||
// set up objectOutput mock
|
||||
ooControl.reset();
|
||||
output.flush();
|
||||
ooControl.setThrowable(new IOException());
|
||||
ooControl.replay();
|
||||
|
||||
try {
|
||||
wrapper.afterRestart(new Long(63));
|
||||
fail("BatchCriticalException was expected");
|
||||
}
|
||||
catch (DataAccessResourceFailureException bce) {
|
||||
assertTrue(bce.getCause() instanceof IOException);
|
||||
}
|
||||
}
|
||||
|
||||
public void testClose() throws IOException, XMLStreamException {
|
||||
|
||||
// set up objectOutput mock
|
||||
output.close();
|
||||
ooControl.replay();
|
||||
|
||||
// set up writer mock
|
||||
writer.close();
|
||||
writerControl.replay();
|
||||
|
||||
wrapper.close();
|
||||
|
||||
// test whether channel, writer and output were closed
|
||||
assertTrue(channel.isClosed());
|
||||
ooControl.verify();
|
||||
writerControl.verify();
|
||||
|
||||
// TEST EXCEPTION HANDLING
|
||||
|
||||
ooControl.reset();
|
||||
output.close();
|
||||
ooControl.setThrowable(new IOException());
|
||||
ooControl.replay();
|
||||
|
||||
try {
|
||||
wrapper.close();
|
||||
fail("BatchCriticalException was expected");
|
||||
}
|
||||
catch (DataAccessResourceFailureException bce) {
|
||||
assertTrue(bce.getCause() instanceof IOException);
|
||||
}
|
||||
|
||||
ooControl.reset();
|
||||
output.close();
|
||||
ooControl.replay();
|
||||
|
||||
writerControl.reset();
|
||||
writer.close();
|
||||
writerControl.setThrowable(new XMLStreamException());
|
||||
writerControl.replay();
|
||||
|
||||
try {
|
||||
wrapper.close();
|
||||
fail("BatchCriticalException was expected");
|
||||
}
|
||||
catch (DataAccessResourceFailureException bce) {
|
||||
assertTrue(bce.getCause() instanceof XMLStreamException);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Test flush() method.
|
||||
* @throws IOException
|
||||
*/
|
||||
public void testFlush() throws IOException {
|
||||
|
||||
// set up objectOutput mock (second call of flush() method will throw an
|
||||
// IOException)
|
||||
output.flush();
|
||||
output.flush();
|
||||
ooControl.setThrowable(new IOException());
|
||||
ooControl.replay();
|
||||
|
||||
// call flush() twice
|
||||
wrapper.flush();
|
||||
try {
|
||||
wrapper.flush();
|
||||
fail("BatchCriticalException was expected");
|
||||
}
|
||||
catch (DataAccessResourceFailureException bce) {
|
||||
assertTrue(bce.getCause() instanceof IOException);
|
||||
}
|
||||
|
||||
// verify method calls
|
||||
ooControl.verify();
|
||||
}
|
||||
|
||||
/**
|
||||
* Test position() and position(int) methods.
|
||||
* @throws IOException
|
||||
*/
|
||||
public void testPosition() throws IOException {
|
||||
|
||||
// set up fileChannel mock
|
||||
channel.position(35);
|
||||
|
||||
// test position()
|
||||
assertEquals(35, wrapper.position());
|
||||
|
||||
// test position(int)
|
||||
wrapper.position(93);
|
||||
assertEquals(93, channel.position());
|
||||
|
||||
// set exception
|
||||
channel.setThrowable(new IOException());
|
||||
|
||||
// test exception handling
|
||||
try {
|
||||
wrapper.position();
|
||||
fail("BatchEnviromentException was expected");
|
||||
}
|
||||
catch (DataAccessResourceFailureException bee) {
|
||||
assertTrue(bee.getCause() instanceof IOException);
|
||||
}
|
||||
|
||||
try {
|
||||
wrapper.position(33);
|
||||
fail("BatchEnviromentException was expected");
|
||||
}
|
||||
catch (DataAccessResourceFailureException bee) {
|
||||
assertTrue(bee.getCause() instanceof IOException);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test size() and truncate() methods.
|
||||
* @throws IOException
|
||||
*/
|
||||
public void testSizeAndTruncate() throws IOException {
|
||||
|
||||
// set up fileChannel mock
|
||||
channel.truncate(53);
|
||||
|
||||
// test size()
|
||||
assertEquals(53, wrapper.size());
|
||||
|
||||
// test truncate(int)
|
||||
wrapper.truncate(39);
|
||||
assertEquals(39, channel.size());
|
||||
|
||||
// set exception
|
||||
channel.setThrowable(new IOException());
|
||||
|
||||
// test exception handling
|
||||
try {
|
||||
wrapper.size();
|
||||
fail("BatchEnviromentException was expected");
|
||||
}
|
||||
catch (DataAccessResourceFailureException bee) {
|
||||
assertTrue(bee.getCause() instanceof IOException);
|
||||
}
|
||||
|
||||
try {
|
||||
wrapper.truncate(66);
|
||||
fail("BatchEnviromentException was expected");
|
||||
}
|
||||
catch (DataAccessResourceFailureException bee) {
|
||||
assertTrue(bee.getCause() instanceof IOException);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Test writeObject() method.
|
||||
* @throws IOException
|
||||
*/
|
||||
public void testWriteObject() throws IOException {
|
||||
//TODO why is "this" used as argument to writeObject?
|
||||
|
||||
// set up objectOutput mock
|
||||
output.writeObject(this);
|
||||
ooControl.replay();
|
||||
|
||||
// write object
|
||||
wrapper.writeObject(this);
|
||||
|
||||
// verify method calls
|
||||
ooControl.verify();
|
||||
}
|
||||
|
||||
/*
|
||||
* Mock for FileChannel
|
||||
*/
|
||||
private static class MockFileChannel extends FileChannel {
|
||||
|
||||
private long position;
|
||||
|
||||
private long size;
|
||||
|
||||
private boolean closed = false;
|
||||
|
||||
private IOException throwable;
|
||||
|
||||
public void setThrowable(IOException throwable) {
|
||||
this.throwable = throwable;
|
||||
}
|
||||
|
||||
public long position() throws IOException {
|
||||
if (throwable != null) {
|
||||
throw throwable;
|
||||
}
|
||||
return position;
|
||||
}
|
||||
|
||||
public FileChannel position(long newPosition) throws IOException {
|
||||
if (throwable != null) {
|
||||
throw throwable;
|
||||
}
|
||||
this.position = newPosition;
|
||||
return null;
|
||||
}
|
||||
|
||||
public long size() throws IOException {
|
||||
if (throwable != null) {
|
||||
throw throwable;
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
||||
public FileChannel truncate(long size) throws IOException {
|
||||
if (throwable != null) {
|
||||
throw throwable;
|
||||
}
|
||||
this.size = size;
|
||||
return null;
|
||||
}
|
||||
|
||||
protected void implCloseChannel() throws IOException {
|
||||
closed = true;
|
||||
}
|
||||
|
||||
public boolean isClosed() {
|
||||
return closed;
|
||||
}
|
||||
|
||||
public void force(boolean metaData) throws IOException {
|
||||
}
|
||||
|
||||
public FileLock lock(long position, long size, boolean shared) throws IOException {
|
||||
return null;
|
||||
}
|
||||
|
||||
public MappedByteBuffer map(MapMode mode, long position, long size) throws IOException {
|
||||
return null;
|
||||
}
|
||||
|
||||
public int read(ByteBuffer dst) throws IOException {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public int read(ByteBuffer dst, long position) throws IOException {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public long read(ByteBuffer[] dsts, int offset, int length) throws IOException {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public long transferFrom(ReadableByteChannel src, long position, long count) throws IOException {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public long transferTo(long position, long count, WritableByteChannel target) throws IOException {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public FileLock tryLock(long position, long size, boolean shared) throws IOException {
|
||||
return null;
|
||||
}
|
||||
|
||||
public int write(ByteBuffer src) throws IOException {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public int write(ByteBuffer src, long position) throws IOException {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public long write(ByteBuffer[] srcs, int offset, int length) throws IOException {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,67 +0,0 @@
|
||||
/*
|
||||
* 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.io.xml;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.springframework.batch.io.xml.XmlErrorHandler;
|
||||
import org.xml.sax.SAXException;
|
||||
import org.xml.sax.SAXParseException;
|
||||
|
||||
/**
|
||||
* Unit test for XmlErrorHandler
|
||||
* @author peter.zozom
|
||||
*/
|
||||
public class XmlErrorHandlerTests extends TestCase {
|
||||
|
||||
XmlErrorHandler handler;
|
||||
|
||||
SAXParseException spe;
|
||||
|
||||
public void setUp() {
|
||||
handler = new XmlErrorHandler();
|
||||
spe = new SAXParseException("test", "pid", "sid", 1, 1);
|
||||
}
|
||||
|
||||
public void testWarning() {
|
||||
try {
|
||||
handler.warning(spe);
|
||||
}
|
||||
catch (SAXException se) {
|
||||
assertSame(spe, se.getException());
|
||||
}
|
||||
}
|
||||
|
||||
public void testError() {
|
||||
try {
|
||||
handler.error(spe);
|
||||
}
|
||||
catch (SAXException se) {
|
||||
assertSame(spe, se.getException());
|
||||
}
|
||||
}
|
||||
|
||||
public void testFatalError() {
|
||||
try {
|
||||
handler.fatalError(spe);
|
||||
}
|
||||
catch (SAXException se) {
|
||||
assertSame(spe, se.getException());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,124 +0,0 @@
|
||||
package org.springframework.batch.io.xml;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import javax.xml.transform.Source;
|
||||
import javax.xml.transform.sax.SAXSource;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.easymock.MockControl;
|
||||
import org.springframework.batch.restart.RestartData;
|
||||
import org.springframework.core.io.FileSystemResource;
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.oxm.Unmarshaller;
|
||||
import org.springframework.oxm.XmlMappingException;
|
||||
import org.springframework.transaction.support.TransactionSynchronization;
|
||||
|
||||
/**
|
||||
* Unit tests for {@link XmlInputSource2}
|
||||
*
|
||||
* @author Robert Kasanicky
|
||||
*/
|
||||
public class XmlInputSource2Tests extends TestCase {
|
||||
|
||||
private XmlInputSource2 inputSource = new XmlInputSource2();
|
||||
|
||||
|
||||
private Resource getInputResource() throws IOException {
|
||||
return new FileSystemResource("src/test/resources/org/springframework/batch/io/xml/test1.xml");
|
||||
}
|
||||
|
||||
//@Override
|
||||
protected void setUp() throws Exception {
|
||||
inputSource.setRecordElementName("book");
|
||||
inputSource.setResource(getInputResource());
|
||||
inputSource.setUnmarshaller(new UnmarshallerStub());
|
||||
inputSource.setUseSaxParser(true);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Regular usage scenario.
|
||||
* The actual xml-to-object mapping is delegated to the injected unmarshaller.
|
||||
*/
|
||||
public void testRead() throws XmlMappingException, IOException {
|
||||
MockControl umControl = MockControl.createControl(Unmarshaller.class);
|
||||
Unmarshaller unmarshaller = (Unmarshaller) umControl.getMock();
|
||||
Object expectedDomainObject = new Object();
|
||||
unmarshaller.unmarshal(null);
|
||||
umControl.setDefaultMatcher(MockControl.ALWAYS_MATCHER);
|
||||
umControl.setDefaultReturnValue(expectedDomainObject);
|
||||
umControl.replay();
|
||||
|
||||
inputSource.setUnmarshaller(unmarshaller);
|
||||
|
||||
//there are two records in the input file
|
||||
assertSame(expectedDomainObject, inputSource.read());
|
||||
assertSame(expectedDomainObject, inputSource.read());
|
||||
assertNull(inputSource.read());
|
||||
}
|
||||
|
||||
public void testReadUntilEnd() {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* In case of rollback uncommited records are read again.
|
||||
*/
|
||||
public void testRollback() {
|
||||
Object uncommited = inputSource.read();
|
||||
inputSource.getSynchronization().afterCompletion(TransactionSynchronization.STATUS_ROLLED_BACK);
|
||||
Object afterRollback = inputSource.read();
|
||||
|
||||
assertEquals(uncommited, afterRollback);
|
||||
}
|
||||
|
||||
/**
|
||||
* Records once marked to be skipped are not returned when read again.
|
||||
*/
|
||||
public void testSkip() {
|
||||
Object first = inputSource.read();
|
||||
inputSource.skip();
|
||||
inputSource.getSynchronization().afterCompletion(TransactionSynchronization.STATUS_ROLLED_BACK);
|
||||
|
||||
Object second = inputSource.read();
|
||||
assertFalse(second.equals(first));
|
||||
}
|
||||
|
||||
/**
|
||||
* In case of restart the input source should continue from the position when restart data was saved.
|
||||
*/
|
||||
public void testRestart() {
|
||||
inputSource.read();
|
||||
RestartData commitPoint = inputSource.getRestartData();
|
||||
Object firstAfterCommit = inputSource.read();
|
||||
inputSource.restoreFrom(commitPoint);
|
||||
assertEquals(firstAfterCommit, inputSource.read());
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a fixed-length prefix of the original xml string instead of mapped object.
|
||||
*
|
||||
* @author Robert Kasanicky
|
||||
*/
|
||||
private static class UnmarshallerStub implements Unmarshaller {
|
||||
|
||||
private static final int PREFIX_LENGTH = 10000;
|
||||
|
||||
public boolean supports(Class clazz) {
|
||||
return true;
|
||||
}
|
||||
|
||||
public Object unmarshal(Source source) throws XmlMappingException, IOException {
|
||||
char[] input = new char[PREFIX_LENGTH];
|
||||
SAXSource saxSource = (SAXSource) source;
|
||||
saxSource.getInputSource().getCharacterStream().read(input);
|
||||
|
||||
return String.valueOf(input);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,428 +0,0 @@
|
||||
/*
|
||||
* 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.io.xml;
|
||||
|
||||
import java.text.ParseException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.springframework.batch.io.exception.BatchEnvironmentException;
|
||||
import org.springframework.batch.io.sample.domain.LineItem;
|
||||
import org.springframework.batch.io.sample.domain.Order;
|
||||
import org.springframework.batch.io.sample.domain.Shipper;
|
||||
import org.springframework.batch.io.xml.xstream.FieldAlias;
|
||||
import org.springframework.batch.io.xml.xstream.Mapping;
|
||||
import org.springframework.batch.io.xml.xstream.XStreamConfiguration;
|
||||
import org.springframework.batch.io.xml.xstream.XStreamFactory;
|
||||
import org.springframework.batch.restart.RestartData;
|
||||
import org.springframework.core.io.ByteArrayResource;
|
||||
import org.springframework.core.io.ClassPathResource;
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.transaction.support.TransactionSynchronization;
|
||||
import org.springframework.util.ClassUtils;
|
||||
|
||||
/**
|
||||
* Integration test for XmlInputTemplate. It tests reading, xml validation, skip
|
||||
* and restart functionality.
|
||||
* @author peter.zozom
|
||||
*/
|
||||
public class XmlInputSourceIntegrationTests extends TestCase {
|
||||
|
||||
private final static String INPUT_NAME = "xmlInputTemplate";
|
||||
|
||||
private XmlInputSource xmlInput;
|
||||
|
||||
private SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss z");
|
||||
|
||||
/**
|
||||
* Set up XmlInputTemplate: create mock for FileLocator and create
|
||||
* XStreamConfiguration object.
|
||||
* @throws Exception
|
||||
*/
|
||||
public void setUp() throws Exception {
|
||||
|
||||
// create mock for file locator
|
||||
Resource resource = new ClassPathResource(ClassUtils.addResourcePathToPackagePath(getClass(),
|
||||
"20070125.testStream.xmlFileStep.xml"));
|
||||
|
||||
// Set up XStreamCfg:
|
||||
XStreamConfiguration streamConfiguration = new XStreamConfiguration();
|
||||
|
||||
// Step 1: set field aliases
|
||||
List aliases = new ArrayList();
|
||||
|
||||
FieldAlias alias = new FieldAlias();
|
||||
alias.setAliasName("org.springframework.batch.io.sample.domain.Customer");
|
||||
alias.setType("org.springframework.batch.io.sample.domain.Order");
|
||||
alias.setFieldName("customer");
|
||||
aliases.add(alias);
|
||||
|
||||
alias = new FieldAlias();
|
||||
alias.setAliasName("org.springframework.batch.io.sample.domain.Shipper");
|
||||
alias.setType("org.springframework.batch.io.sample.domain.Order");
|
||||
alias.setFieldName("shipper");
|
||||
aliases.add(alias);
|
||||
|
||||
streamConfiguration.setFieldAliases(aliases);
|
||||
|
||||
// Step 2: set mappings
|
||||
List mappings = new ArrayList();
|
||||
|
||||
Mapping mapping = new Mapping();
|
||||
mapping.setClassName("org.springframework.batch.io.sample.domain.Order");
|
||||
mapping.setNamespaceURI("http://adsj.accenture.com/purchaseorders");
|
||||
mapping.setLocalPart("order");
|
||||
mapping.setPrefix("");
|
||||
mappings.add(mapping);
|
||||
|
||||
mapping = new Mapping();
|
||||
mapping.setClassName("org.springframework.batch.io.sample.domain.Customer");
|
||||
mapping.setNamespaceURI("http://adsj.accenture.com/purchaseorders");
|
||||
mapping.setLocalPart("customer");
|
||||
mapping.setPrefix("");
|
||||
mappings.add(mapping);
|
||||
|
||||
mapping = new Mapping();
|
||||
mapping.setClassName("org.springframework.batch.io.sample.domain.LineItem");
|
||||
mapping.setNamespaceURI("http://adsj.accenture.com/purchaseorders");
|
||||
mapping.setLocalPart("lineItem");
|
||||
mapping.setPrefix("");
|
||||
mappings.add(mapping);
|
||||
|
||||
mapping = new Mapping();
|
||||
mapping.setClassName("org.springframework.batch.io.sample.domain.Shipper");
|
||||
mapping.setNamespaceURI("http://adsj.accenture.com/purchaseorders");
|
||||
mapping.setLocalPart("shipper");
|
||||
mapping.setPrefix("");
|
||||
mappings.add(mapping);
|
||||
|
||||
streamConfiguration.setMappings(mappings);
|
||||
|
||||
// Set up input template
|
||||
xmlInput = new XmlInputSource() {
|
||||
public void registerSynchronization() {
|
||||
}
|
||||
};
|
||||
|
||||
xmlInput.setResource(resource);
|
||||
xmlInput.setEncoding("UTF-8");
|
||||
xmlInput.setName(INPUT_NAME);
|
||||
XStreamFactory factory = new XStreamFactory();
|
||||
factory.setConfig(streamConfiguration);
|
||||
xmlInput.setInputFactory(factory);
|
||||
}
|
||||
|
||||
public void tearDown() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Test read functionality.
|
||||
* @throws ParseException
|
||||
*/
|
||||
public void testRead() throws ParseException {
|
||||
|
||||
xmlInput.setValidating(false);
|
||||
xmlInput.open();
|
||||
|
||||
// READ FIRST RECORD
|
||||
Object result = xmlInput.read();
|
||||
|
||||
// is it Order?
|
||||
assertTrue(result instanceof Order);
|
||||
Order order = (Order) result;
|
||||
// verify customer
|
||||
assertNotNull(order.getCustomer());
|
||||
assertEquals("Gladys Kravitz", order.getCustomer().getName());
|
||||
assertEquals("Anytown, PA", order.getCustomer().getAddress());
|
||||
assertEquals(34, order.getCustomer().getAge());
|
||||
assertEquals(0, order.getCustomer().getMoo());
|
||||
assertEquals(0, order.getCustomer().getPoo());
|
||||
// verify date
|
||||
assertEquals(sdf.parse("2003-01-07 14:16:00 GMT"), order.getDate());
|
||||
// verify line items
|
||||
List items = order.getLineItems();
|
||||
assertEquals(2, items.size());
|
||||
LineItem item = (LineItem) items.get(0);
|
||||
assertEquals("Burnham's Celestial Handbook, Vol 1", item.getDescription());
|
||||
assertEquals(5.0, item.getPerUnitOunces(), 0.0);
|
||||
assertEquals(21.79, item.getPrice(), 0.0);
|
||||
assertEquals(2, item.getQuantity());
|
||||
item = (LineItem) items.get(1);
|
||||
assertEquals("Burnham's Celestial Handbook, Vol 2", item.getDescription());
|
||||
assertEquals(5.0, item.getPerUnitOunces(), 0.0);
|
||||
assertEquals(19.89, item.getPrice(), 0.0);
|
||||
assertEquals(2, item.getQuantity());
|
||||
// verify shipper
|
||||
Shipper shipper = order.getShipper();
|
||||
assertEquals("ZipShip", shipper.getName());
|
||||
assertEquals(0.74, shipper.getPerOunceRate(), 0.0);
|
||||
|
||||
// READ SECOND RECORD
|
||||
result = xmlInput.read();
|
||||
|
||||
// is it Order?
|
||||
assertTrue(result instanceof Order);
|
||||
order = (Order) result;
|
||||
// verify customer
|
||||
assertNotNull(order.getCustomer());
|
||||
assertEquals("John Smith", order.getCustomer().getName());
|
||||
assertEquals("Chicago, IL", order.getCustomer().getAddress());
|
||||
assertEquals(46, order.getCustomer().getAge());
|
||||
assertEquals(0, order.getCustomer().getMoo());
|
||||
assertEquals(0, order.getCustomer().getPoo());
|
||||
// verify date
|
||||
assertEquals(sdf.parse("2003-01-07 14:16:02 GMT"), order.getDate());
|
||||
// verify line items
|
||||
items = order.getLineItems();
|
||||
assertEquals(3, items.size());
|
||||
item = (LineItem) items.get(0);
|
||||
assertEquals("XmlBeans in Action", item.getDescription());
|
||||
assertEquals(3.0, item.getPerUnitOunces(), 0.0);
|
||||
assertEquals(41.29, item.getPrice(), 0.0);
|
||||
assertEquals(1, item.getQuantity());
|
||||
item = (LineItem) items.get(1);
|
||||
assertEquals("JSR-173", item.getDescription());
|
||||
assertEquals(1.0, item.getPerUnitOunces(), 0.0);
|
||||
assertEquals(11.99, item.getPrice(), 0.0);
|
||||
assertEquals(5, item.getQuantity());
|
||||
item = (LineItem) items.get(2);
|
||||
assertEquals("Teach Yourself XML in 21 days", item.getDescription());
|
||||
assertEquals(1.0, item.getPerUnitOunces(), 0.0);
|
||||
assertEquals(35.49, item.getPrice(), 0.0);
|
||||
assertEquals(1, item.getQuantity());
|
||||
// verify shipper
|
||||
shipper = order.getShipper();
|
||||
assertEquals("ZipShip", shipper.getName());
|
||||
assertEquals(0.74, shipper.getPerOunceRate(), 0.0);
|
||||
|
||||
// READ LAST RECORD
|
||||
result = xmlInput.read();
|
||||
|
||||
// is it Order?
|
||||
assertTrue(result instanceof Order);
|
||||
order = (Order) result;
|
||||
// verify customer
|
||||
assertNotNull(order.getCustomer());
|
||||
assertEquals("Peter Newman", order.getCustomer().getName());
|
||||
assertEquals("Cleveland, OH", order.getCustomer().getAddress());
|
||||
assertEquals(23, order.getCustomer().getAge());
|
||||
assertEquals(0, order.getCustomer().getMoo());
|
||||
assertEquals(0, order.getCustomer().getPoo());
|
||||
// verify date
|
||||
assertEquals(sdf.parse("2003-01-07 14:16:35 GMT"), order.getDate());
|
||||
// verify line items
|
||||
items = order.getLineItems();
|
||||
assertEquals(1, items.size());
|
||||
item = (LineItem) items.get(0);
|
||||
assertEquals("Java 6", item.getDescription());
|
||||
assertEquals(2.0, item.getPerUnitOunces(), 0.0);
|
||||
assertEquals(12.79, item.getPrice(), 0.0);
|
||||
assertEquals(3, item.getQuantity());
|
||||
// verify shipper
|
||||
shipper = order.getShipper();
|
||||
assertEquals("UPS", shipper.getName());
|
||||
assertEquals(0.69, shipper.getPerOunceRate(), 0.0);
|
||||
|
||||
// all records were processed already
|
||||
assertNull(xmlInput.read());
|
||||
|
||||
// verify statistics TODO
|
||||
// Map statistics = xmlInput.getStatistics();
|
||||
// assertEquals("4",
|
||||
// statistics.get(XmlInputTemplate.READ_STATISTICS_NAME));
|
||||
|
||||
xmlInput.close();
|
||||
}
|
||||
|
||||
/**
|
||||
* Test XML validation
|
||||
*/
|
||||
public void testValidation() {
|
||||
|
||||
// turn on xml validation
|
||||
xmlInput.setValidating(true);
|
||||
// TEST 1: parse valid xml
|
||||
xmlInput.open();
|
||||
xmlInput.close();
|
||||
|
||||
}
|
||||
|
||||
public void testInvalidXml() throws Exception {
|
||||
|
||||
xmlInput.setValidating(true);
|
||||
|
||||
// TEST 2: parse invalid xml
|
||||
xmlInput.setResource(new ByteArrayResource("<invalid><xml>".getBytes()));
|
||||
|
||||
try {
|
||||
xmlInput.open();
|
||||
fail("Parsing invalid xml file. Exception should be thrown.");
|
||||
}
|
||||
catch (BatchEnvironmentException bee) {
|
||||
assertTrue(true);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Test skip functioanlity.
|
||||
* @throws ParseException
|
||||
*/
|
||||
public void testSkip() throws ParseException {
|
||||
|
||||
xmlInput.setValidating(false);
|
||||
xmlInput.open();
|
||||
|
||||
// read first record
|
||||
xmlInput.read();
|
||||
// mark it as skipped
|
||||
xmlInput.skip();
|
||||
// read second record
|
||||
xmlInput.read();
|
||||
// read third record
|
||||
xmlInput.read();
|
||||
// mark it as skipped and rollback
|
||||
xmlInput.skip();
|
||||
xmlInput.afterCompletion(TransactionSynchronization.STATUS_ROLLED_BACK);
|
||||
|
||||
// read second record again (first was skipped)
|
||||
Object result = xmlInput.read();
|
||||
|
||||
// is it Order?
|
||||
assertTrue(result instanceof Order);
|
||||
Order order = (Order) result;
|
||||
// verify customer
|
||||
assertNotNull(order.getCustomer());
|
||||
assertEquals("John Smith", order.getCustomer().getName());
|
||||
assertEquals("Chicago, IL", order.getCustomer().getAddress());
|
||||
assertEquals(46, order.getCustomer().getAge());
|
||||
assertEquals(0, order.getCustomer().getMoo());
|
||||
assertEquals(0, order.getCustomer().getPoo());
|
||||
// verify date
|
||||
assertEquals(sdf.parse("2003-01-07 14:16:02 GMT"), order.getDate());
|
||||
// verify line items
|
||||
List items = order.getLineItems();
|
||||
assertEquals(3, items.size());
|
||||
LineItem item = (LineItem) items.get(0);
|
||||
assertEquals("XmlBeans in Action", item.getDescription());
|
||||
assertEquals(3.0, item.getPerUnitOunces(), 0.0);
|
||||
assertEquals(41.29, item.getPrice(), 0.0);
|
||||
assertEquals(1, item.getQuantity());
|
||||
item = (LineItem) items.get(1);
|
||||
assertEquals("JSR-173", item.getDescription());
|
||||
assertEquals(1.0, item.getPerUnitOunces(), 0.0);
|
||||
assertEquals(11.99, item.getPrice(), 0.0);
|
||||
assertEquals(5, item.getQuantity());
|
||||
item = (LineItem) items.get(2);
|
||||
assertEquals("Teach Yourself XML in 21 days", item.getDescription());
|
||||
assertEquals(1.0, item.getPerUnitOunces(), 0.0);
|
||||
assertEquals(35.49, item.getPrice(), 0.0);
|
||||
assertEquals(1, item.getQuantity());
|
||||
// verify shipper
|
||||
Shipper shipper = order.getShipper();
|
||||
assertEquals("ZipShip", shipper.getName());
|
||||
assertEquals(0.74, shipper.getPerOunceRate(), 0.0);
|
||||
|
||||
// No records left, third record should be skipped
|
||||
assertNull(xmlInput.read());
|
||||
|
||||
// verify statistics TODO
|
||||
// Map statistics = xmlInput.getStatistics();
|
||||
// assertEquals("4",
|
||||
// statistics.get(XmlInputTemplate.READ_STATISTICS_NAME));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test restart functionality.
|
||||
* @throws ParseException
|
||||
*/
|
||||
public void testRestart() throws ParseException {
|
||||
|
||||
xmlInput.open();
|
||||
|
||||
// read first record and commit it
|
||||
xmlInput.read();
|
||||
xmlInput.afterCompletion(TransactionSynchronization.STATUS_COMMITTED);
|
||||
// read second record and commit it
|
||||
xmlInput.read();
|
||||
xmlInput.afterCompletion(TransactionSynchronization.STATUS_COMMITTED);
|
||||
// read third record
|
||||
xmlInput.read();
|
||||
xmlInput.afterCompletion(TransactionSynchronization.STATUS_ROLLED_BACK);
|
||||
RestartData restartData = xmlInput.getRestartData();
|
||||
|
||||
xmlInput.close();
|
||||
|
||||
xmlInput.open();
|
||||
xmlInput.restoreFrom(restartData);
|
||||
Object result = xmlInput.read();
|
||||
|
||||
// is it Order?
|
||||
assertTrue(result instanceof Order);
|
||||
Order order = (Order) result;
|
||||
// verify customer
|
||||
assertNotNull(order.getCustomer());
|
||||
assertEquals("Peter Newman", order.getCustomer().getName());
|
||||
assertEquals("Cleveland, OH", order.getCustomer().getAddress());
|
||||
assertEquals(23, order.getCustomer().getAge());
|
||||
assertEquals(0, order.getCustomer().getMoo());
|
||||
assertEquals(0, order.getCustomer().getPoo());
|
||||
// verify date
|
||||
assertEquals(sdf.parse("2003-01-07 14:16:35 GMT"), order.getDate());
|
||||
// verify line items
|
||||
List items = order.getLineItems();
|
||||
assertEquals(1, items.size());
|
||||
LineItem item = (LineItem) items.get(0);
|
||||
assertEquals("Java 6", item.getDescription());
|
||||
assertEquals(2.0, item.getPerUnitOunces(), 0.0);
|
||||
assertEquals(12.79, item.getPrice(), 0.0);
|
||||
assertEquals(3, item.getQuantity());
|
||||
// verify shipper
|
||||
Shipper shipper = order.getShipper();
|
||||
assertEquals("UPS", shipper.getName());
|
||||
assertEquals(0.69, shipper.getPerOunceRate(), 0.0);
|
||||
|
||||
// all records were processed already
|
||||
assertNull(xmlInput.read());
|
||||
|
||||
// verify statistics TODO
|
||||
// Map statistics = xmlInput.getStatistics();
|
||||
// assertEquals("4",
|
||||
// statistics.get(XmlInputTemplate.READ_STATISTICS_NAME));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests null resource
|
||||
* @throws Exception
|
||||
*/
|
||||
public void testGetFileLocatorStrategyWithNullParam() throws Exception {
|
||||
|
||||
// set file locator strategy to null
|
||||
xmlInput.setResource(null);
|
||||
try {
|
||||
xmlInput.afterPropertiesSet();
|
||||
fail("Expected IllegalArgumentException");
|
||||
}
|
||||
catch (IllegalArgumentException e) {
|
||||
// expected
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,284 +0,0 @@
|
||||
/*
|
||||
* 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.io.xml;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
|
||||
import javax.xml.parsers.FactoryConfigurationError;
|
||||
import javax.xml.parsers.ParserConfigurationException;
|
||||
import javax.xml.parsers.SAXParser;
|
||||
import javax.xml.parsers.SAXParserFactory;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.easymock.MockControl;
|
||||
import org.springframework.batch.io.exception.BatchCriticalException;
|
||||
import org.springframework.batch.io.exception.BatchEnvironmentException;
|
||||
import org.springframework.batch.io.xml.ObjectInput;
|
||||
import org.springframework.batch.io.xml.ObjectInputFactory;
|
||||
import org.springframework.batch.io.xml.XmlInputSource;
|
||||
import org.springframework.core.io.ClassPathResource;
|
||||
import org.springframework.core.io.FileSystemResource;
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.transaction.support.TransactionSynchronization;
|
||||
import org.springframework.util.ClassUtils;
|
||||
import org.xml.sax.Parser;
|
||||
import org.xml.sax.SAXException;
|
||||
import org.xml.sax.SAXNotRecognizedException;
|
||||
import org.xml.sax.SAXNotSupportedException;
|
||||
import org.xml.sax.XMLReader;
|
||||
import org.xml.sax.helpers.DefaultHandler;
|
||||
|
||||
/**
|
||||
* Additional unit tests, which test feuatores not tested with
|
||||
* XmlInputTemplateIntegrationTest
|
||||
* @author peter.zozom
|
||||
*/
|
||||
public class XmlInputSourceTests extends TestCase {
|
||||
|
||||
private MockControl oifControl;
|
||||
|
||||
private MockControl oiControl;
|
||||
|
||||
private ObjectInputFactory objectInputFactory;
|
||||
|
||||
private ObjectInput objectInput;
|
||||
|
||||
private XmlInputSource input;
|
||||
|
||||
/**
|
||||
* Set up XmlInputTemplate: create mock for FileLocator,
|
||||
* ObjectInputFactory and ObjectInput
|
||||
*/
|
||||
public void setUp() {
|
||||
|
||||
Resource resource = new ClassPathResource(ClassUtils.addResourcePathToPackagePath(getClass(), "20070125.testStream.xmlFileStep.xml"));
|
||||
|
||||
// create mock for ObjectInput
|
||||
oiControl = MockControl.createControl(ObjectInput.class);
|
||||
objectInput = (ObjectInput) oiControl.getMock();
|
||||
|
||||
// create mock for ObjectInputFactory
|
||||
oifControl = MockControl.createControl(ObjectInputFactory.class);
|
||||
objectInputFactory = (ObjectInputFactory) oifControl.getMock();
|
||||
objectInputFactory.createObjectInput(resource, "UTF-8");
|
||||
oifControl.setReturnValue(objectInput, 1);
|
||||
oifControl.replay();
|
||||
|
||||
// create input template
|
||||
input = new XmlInputSource() {
|
||||
protected void registerSynchronization() {
|
||||
}
|
||||
|
||||
protected SAXParserFactory getSaxFactory() throws FactoryConfigurationError {
|
||||
return new MockSAXFactory();
|
||||
}
|
||||
};
|
||||
|
||||
// set up input template
|
||||
input.setValidating(false);
|
||||
input.setName("test_name");
|
||||
input.setInputFactory(objectInputFactory);
|
||||
|
||||
input.setResource(resource);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test init called twice (2nd call should do nothing)
|
||||
*/
|
||||
public void testDoubleInit() {
|
||||
|
||||
// set up objectInput mock
|
||||
objectInput.position();
|
||||
oiControl.setReturnValue(3, 1);
|
||||
oiControl.replay();
|
||||
|
||||
// call init
|
||||
input.open();
|
||||
|
||||
// call init again - nothing should happen
|
||||
input.open();
|
||||
|
||||
// verify method calls for each mock object
|
||||
oifControl.verify();
|
||||
oiControl.verify();
|
||||
}
|
||||
|
||||
/**
|
||||
* Test exception handling in validateInputFile() method
|
||||
*/
|
||||
public void testExceptionsInValidationMethod() {
|
||||
|
||||
oifControl.reset();
|
||||
oifControl.replay();
|
||||
// set up objectInput mock
|
||||
oiControl.replay();
|
||||
input.setValidating(true);
|
||||
|
||||
try {
|
||||
// call init again - nothing should happen
|
||||
input.open();
|
||||
fail("ParserConfigurationException was expected");
|
||||
}
|
||||
catch (BatchEnvironmentException bee) {
|
||||
// ParserConfigurationException is expected
|
||||
assertTrue(bee.getCause() instanceof ParserConfigurationException);
|
||||
}
|
||||
|
||||
FileSystemResource resource = new FileSystemResource("FooDummy.xml");
|
||||
assertTrue(!resource.exists());
|
||||
input.setResource(resource);
|
||||
|
||||
try {
|
||||
// call init again - nothing should happen
|
||||
input.open();
|
||||
fail("BatchCriticalException was expected");
|
||||
}
|
||||
catch (BatchCriticalException bee) {
|
||||
// IOException is expected
|
||||
assertTrue(bee.getCause() instanceof IOException);
|
||||
}
|
||||
|
||||
// verify method calls for each mock object
|
||||
oifControl.verify();
|
||||
oiControl.verify();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Test exception handling in read() method
|
||||
* @throws ClassNotFoundException
|
||||
* @throws IOException
|
||||
*/
|
||||
public void testExceptionsInReadMethod() throws ClassNotFoundException, IOException {
|
||||
|
||||
// set up objectInput mock
|
||||
objectInput.position();
|
||||
oiControl.setReturnValue(3, 1);
|
||||
objectInput.readObject();
|
||||
oiControl.setThrowable(new IOException());
|
||||
objectInput.readObject();
|
||||
oiControl.setThrowable(new ClassNotFoundException());
|
||||
oiControl.replay();
|
||||
|
||||
// call init
|
||||
input.open();
|
||||
|
||||
try {
|
||||
input.read();
|
||||
fail("BatchCriticalException caused by IOException was expected");
|
||||
}
|
||||
catch (BatchCriticalException bce) {
|
||||
assertTrue(bce.getCause() instanceof IOException);
|
||||
}
|
||||
|
||||
try {
|
||||
input.read();
|
||||
fail("BatchCriticalException caused by ClassNotFoundException was expected");
|
||||
}
|
||||
catch (BatchCriticalException bee) {
|
||||
assertTrue(bee.getCause() instanceof ClassNotFoundException);
|
||||
}
|
||||
|
||||
// verify method calls for each mock object
|
||||
oifControl.verify();
|
||||
oiControl.verify();
|
||||
}
|
||||
|
||||
/**
|
||||
* Test afterCompletition() method with transaction status "UNKNOWN"
|
||||
*/
|
||||
public void testTransactionUnknownStatus() {
|
||||
|
||||
// set up ObjectInput mock
|
||||
objectInput.position();
|
||||
oiControl.setReturnValue(3, 1);
|
||||
oiControl.replay();
|
||||
|
||||
input.open();
|
||||
|
||||
// call afterCompletition method with unknown status - nothing should
|
||||
// happen
|
||||
input.afterCompletion(TransactionSynchronization.STATUS_UNKNOWN);
|
||||
|
||||
// verify method calls for each mock object
|
||||
oifControl.verify();
|
||||
oiControl.verify();
|
||||
}
|
||||
|
||||
/*
|
||||
* Mock for SAXParserFactory, which either throws
|
||||
* ParserConfigurationException or returns MockSAXParser
|
||||
*/
|
||||
private static class MockSAXFactory extends SAXParserFactory {
|
||||
|
||||
private static int counter = 0;
|
||||
|
||||
public boolean getFeature(String name) throws ParserConfigurationException, SAXNotRecognizedException,
|
||||
SAXNotSupportedException {
|
||||
return false;
|
||||
}
|
||||
|
||||
public SAXParser newSAXParser() throws ParserConfigurationException, SAXException {
|
||||
counter++;
|
||||
if (counter % 2 != 0) {
|
||||
throw new ParserConfigurationException();
|
||||
}
|
||||
return new MockSAXParser();
|
||||
}
|
||||
|
||||
public void setFeature(String name, boolean value) throws ParserConfigurationException,
|
||||
SAXNotRecognizedException, SAXNotSupportedException {
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Mock for SAXParser, which throws IOException in parse(java.io.File,
|
||||
* org.xml.sax.helpers.DefaultHandler) method
|
||||
*/
|
||||
private static class MockSAXParser extends SAXParser {
|
||||
|
||||
public void parse(File f, DefaultHandler dh) throws SAXException, IOException {
|
||||
throw new IOException();
|
||||
}
|
||||
|
||||
public Parser getParser() throws SAXException {
|
||||
return null;
|
||||
}
|
||||
|
||||
public Object getProperty(String name) throws SAXNotRecognizedException, SAXNotSupportedException {
|
||||
return null;
|
||||
}
|
||||
|
||||
public XMLReader getXMLReader() throws SAXException {
|
||||
return null;
|
||||
}
|
||||
|
||||
public boolean isNamespaceAware() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean isValidating() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public void setProperty(String name, Object value) throws SAXNotRecognizedException, SAXNotSupportedException {
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,262 +0,0 @@
|
||||
/*
|
||||
* 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.io.xml;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.easymock.MockControl;
|
||||
import org.easymock.internal.Range;
|
||||
import org.springframework.batch.restart.RestartData;
|
||||
import org.springframework.core.io.FileSystemResource;
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.dao.DataAccessResourceFailureException;
|
||||
import org.springframework.transaction.support.TransactionSynchronization;
|
||||
|
||||
/**
|
||||
* Unit tests for XmlOutputTemplate
|
||||
* @author peter.zozom
|
||||
*
|
||||
*/
|
||||
public class XmlOutputSourceTests extends TestCase {
|
||||
|
||||
private final static String OUTPUT_NAME = "xmlOutputTemplate";
|
||||
|
||||
private XmlOutputSource xmlOutput;
|
||||
|
||||
private MockControl ooControl;
|
||||
|
||||
private ObjectOutput objectOutput;
|
||||
|
||||
private MockControl oofControl;
|
||||
|
||||
private ObjectOutputFactory objectOutputFactory;
|
||||
|
||||
/**
|
||||
* Set up XmlOutputTemplate: create mock for FileLocator,
|
||||
* ObjectOutputFactory and ObjectOutput.
|
||||
*/
|
||||
public void setUp() throws Exception {
|
||||
|
||||
// create File object
|
||||
Resource file = new FileSystemResource(File.createTempFile("xml-output-test-", ".xml"));
|
||||
|
||||
// Create mock for ObjectOutput
|
||||
ooControl = MockControl.createControl(ObjectOutput.class);
|
||||
objectOutput = (ObjectOutput) ooControl.getMock();
|
||||
|
||||
// Create mock for ObjectOutputFactory, which will return mock
|
||||
// ObjectOutput
|
||||
oofControl = MockControl.createControl(ObjectOutputFactory.class);
|
||||
objectOutputFactory = (ObjectOutputFactory) oofControl.getMock();
|
||||
objectOutputFactory.createObjectOutput(file, "UTF-8");
|
||||
oofControl.setReturnValue(objectOutput, new Range(1,2));
|
||||
oofControl.replay();
|
||||
|
||||
// Create output template
|
||||
xmlOutput = new XmlOutputSource() {
|
||||
protected void registerSynchronization() {
|
||||
}
|
||||
};
|
||||
|
||||
// Set up output template
|
||||
xmlOutput.setResource(file);
|
||||
xmlOutput.setEncoding("UTF-8");
|
||||
xmlOutput.setName(OUTPUT_NAME);
|
||||
xmlOutput.setOutputFactory(objectOutputFactory);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests write and close method. Also tests statistics.
|
||||
* @throws IOException
|
||||
*/
|
||||
public void testWrite() throws IOException {
|
||||
|
||||
// initialize xmlOutput
|
||||
xmlOutput.open();
|
||||
|
||||
// set up ObjectOutput mock
|
||||
objectOutput.writeObject(this);
|
||||
objectOutput.writeObject(this);
|
||||
objectOutput.close();
|
||||
ooControl.replay();
|
||||
|
||||
// call write method
|
||||
xmlOutput.write(this);
|
||||
|
||||
// verify statistics TODO
|
||||
// Map statistics = xmlOutput.getStatistics();
|
||||
// assertEquals("1", statistics.get(XmlOutputTemplate.WRITTEN_STATISTICS_NAME));
|
||||
|
||||
// call write method again
|
||||
xmlOutput.write(this);
|
||||
|
||||
// call close method
|
||||
xmlOutput.close();
|
||||
|
||||
// verify statistics again: count of written objects should be changed TODO
|
||||
// statistics = xmlOutput.getStatistics();
|
||||
// assertEquals("2", statistics.get(XmlOutputTemplate.WRITTEN_STATISTICS_NAME));
|
||||
|
||||
// verify method calls for each mock
|
||||
oofControl.verify();
|
||||
ooControl.verify();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests handling IOException raised within write() method
|
||||
* @throws IOException
|
||||
*/
|
||||
public void testWriteWithIOException() throws IOException {
|
||||
|
||||
// initialize xmlOutput
|
||||
xmlOutput.open();
|
||||
|
||||
// set up ObjectOutput mock
|
||||
objectOutput.writeObject(this);
|
||||
IOException ioe = new IOException("test");
|
||||
ooControl.setThrowable(ioe);
|
||||
objectOutput.close();
|
||||
ooControl.replay();
|
||||
|
||||
try {
|
||||
xmlOutput.write(this);
|
||||
fail("BatchCriticalException was expected");
|
||||
}
|
||||
catch (DataAccessResourceFailureException bce) {
|
||||
// exceptiow was expected: caused by ioe
|
||||
assertSame(ioe, bce.getCause());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests commit and rollback functionality.
|
||||
* @throws IOException
|
||||
*/
|
||||
public void testCommitAndRollback() throws IOException {
|
||||
|
||||
// Set up ObjectOutput mock:
|
||||
objectOutput.writeObject(null);
|
||||
|
||||
// STEP1: commit: flush output and remember commit position
|
||||
objectOutput.flush();
|
||||
objectOutput.position();
|
||||
ooControl.setReturnValue(102);
|
||||
// STEP2: rollback: check size, truncate output and set new position
|
||||
objectOutput.size();
|
||||
ooControl.setReturnValue(500); // size(=500) > newSize(=102)
|
||||
objectOutput.position(102);
|
||||
objectOutput.truncate(102);
|
||||
// STEP3: rollback with bad output size
|
||||
objectOutput.size();
|
||||
ooControl.setReturnValue(10); // size(=10) < newSize(=102)
|
||||
ooControl.replay();
|
||||
|
||||
// initialize xmlOutput
|
||||
xmlOutput.open();
|
||||
xmlOutput.write(null); // because output writer is initialized in write method.
|
||||
|
||||
// test commit and rollback
|
||||
// STEP1: commit
|
||||
xmlOutput.afterCompletion(TransactionSynchronization.STATUS_COMMITTED);
|
||||
// STEP2: rollback
|
||||
xmlOutput.afterCompletion(TransactionSynchronization.STATUS_ROLLED_BACK);
|
||||
// STEP3: rollback with bad output size
|
||||
try {
|
||||
xmlOutput.afterCompletion(TransactionSynchronization.STATUS_ROLLED_BACK);
|
||||
fail("Exception was expected because of bad output size");
|
||||
}
|
||||
catch (IllegalStateException bce) {
|
||||
// exception is expected
|
||||
assertTrue(true);
|
||||
}
|
||||
|
||||
// STEP4: call afterCompletition with status "UNKNOWN" - nothing should
|
||||
// happen
|
||||
xmlOutput.afterCompletion(TransactionSynchronization.STATUS_UNKNOWN);
|
||||
|
||||
// verify method calls for each mock
|
||||
oofControl.verify();
|
||||
ooControl.verify();
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests restart functionality.
|
||||
* @throws IOException
|
||||
*/
|
||||
public void testRestart() throws IOException {
|
||||
|
||||
// Set up ObjectOutput mock:
|
||||
objectOutput.writeObject(null);
|
||||
// - set position (=restartData)
|
||||
objectOutput.position();
|
||||
ooControl.setReturnValue(23001);
|
||||
objectOutput.close();
|
||||
|
||||
objectOutput.writeObject(null);
|
||||
|
||||
// - after restart should be called with restart data
|
||||
objectOutput.afterRestart(new Long(23001));
|
||||
// - and finaly set size (it should be verified: size >
|
||||
// newSize(=restartData))
|
||||
objectOutput.size();
|
||||
ooControl.setReturnValue(54301);
|
||||
ooControl.replay();
|
||||
|
||||
// initialize xmlOutput
|
||||
xmlOutput.open();
|
||||
|
||||
xmlOutput.write(null); // because output writer is initialized in write method.
|
||||
|
||||
// get restart data
|
||||
RestartData restartData = xmlOutput.getRestartData();
|
||||
assertEquals("23001", restartData.getProperties().getProperty(XmlOutputSource.RESTART_DATA_NAME));
|
||||
xmlOutput.close();
|
||||
|
||||
// init for restart
|
||||
xmlOutput.open();
|
||||
|
||||
xmlOutput.restoreFrom(restartData);
|
||||
|
||||
xmlOutput.write(null); // because output writer is initialized in write method.
|
||||
|
||||
// verify method calls for each mock
|
||||
oofControl.verify();
|
||||
ooControl.verify();
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests getFileLocatorStrategy() with fileLocatorStrategy = null
|
||||
*/
|
||||
public void testGetFileLocatorStrategyWithNullParam() throws Exception {
|
||||
|
||||
// set file locator strategy to null
|
||||
xmlOutput.setResource(null);
|
||||
try {
|
||||
xmlOutput.afterPropertiesSet();
|
||||
fail("Expected IllegalArgumentException");
|
||||
}
|
||||
catch (IllegalArgumentException e) {
|
||||
// expected
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,234 +0,0 @@
|
||||
/*
|
||||
* 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.io.xml.xstream;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.springframework.batch.io.exception.BatchEnvironmentException;
|
||||
import org.springframework.core.io.ClassPathResource;
|
||||
|
||||
/**
|
||||
* Integration tests for XStreamConfigurationFactory.
|
||||
* @author peter.zozom
|
||||
* @author Dave Syer
|
||||
*/
|
||||
public class XStreamConfigurationFactoryBeanIntegrationTests extends TestCase {
|
||||
|
||||
XStreamConfigurationFactoryBean factory;
|
||||
|
||||
public void setUp() {
|
||||
factory = new XStreamConfigurationFactoryBean();
|
||||
}
|
||||
|
||||
/**
|
||||
* Test getXStreamCofiguration() method.
|
||||
* @throws Exception
|
||||
*/
|
||||
public void testGetXStreamConfiguration() throws Exception {
|
||||
|
||||
// set config file
|
||||
factory.setConfigFile(new ClassPathResource("xstream-config-test.xml", getClass()));
|
||||
// get XStreamConfiguration
|
||||
factory.afterPropertiesSet();
|
||||
XStreamConfiguration config = (XStreamConfiguration) factory.getObject();
|
||||
|
||||
// test mode
|
||||
assertEquals(1003, config.getMode());
|
||||
|
||||
// test root element name
|
||||
assertEquals("root_test", config.getRootElementName());
|
||||
|
||||
// test root element attributes
|
||||
Map rea = config.getRootElementAttributes();
|
||||
assertNotNull(rea);
|
||||
assertEquals(2, rea.size());
|
||||
assertEquals("root-elementAttr_value1", rea.get("root-elementAttr_key1"));
|
||||
assertEquals("root-elementAttr_value2", rea.get("root-elementAttr_key2"));
|
||||
|
||||
// test class aliases
|
||||
List aliases = config.getClassAliases();
|
||||
assertNotNull(aliases);
|
||||
assertEquals(2, aliases.size());
|
||||
|
||||
ClassAlias classAlias = (ClassAlias) aliases.get(0);
|
||||
assertEquals("class-alias_name1", classAlias.getName());
|
||||
assertEquals("class-alias_type1", classAlias.getType());
|
||||
assertEquals("class-alias_di1", classAlias.getDefaultImplementation());
|
||||
|
||||
classAlias = (ClassAlias) aliases.get(1);
|
||||
assertEquals("class-alias_name2", classAlias.getName());
|
||||
assertEquals("class-alias_type2", classAlias.getType());
|
||||
assertEquals("class-alias_di2", classAlias.getDefaultImplementation());
|
||||
|
||||
// test type aliases
|
||||
aliases = config.getTypeAliases();
|
||||
assertNotNull(aliases);
|
||||
assertEquals(2, aliases.size());
|
||||
|
||||
TypeAlias typeAlias = (TypeAlias) aliases.get(0);
|
||||
assertEquals("type-alias_name1", typeAlias.getName());
|
||||
assertEquals("type-alias_type1", typeAlias.getType());
|
||||
|
||||
typeAlias = (TypeAlias) aliases.get(1);
|
||||
assertEquals("type-alias_name2", typeAlias.getName());
|
||||
assertEquals("type-alias_type2", typeAlias.getType());
|
||||
|
||||
// test field aliases
|
||||
aliases = config.getFieldAliases();
|
||||
assertNotNull(aliases);
|
||||
assertEquals(2, aliases.size());
|
||||
|
||||
FieldAlias fieldAlias = (FieldAlias) aliases.get(0);
|
||||
assertEquals("field-alias_name1", fieldAlias.getAliasName());
|
||||
assertEquals("field-alias_type1", fieldAlias.getType());
|
||||
assertEquals("field1", fieldAlias.getFieldName());
|
||||
|
||||
fieldAlias = (FieldAlias) aliases.get(1);
|
||||
assertEquals("field-alias_name2", fieldAlias.getAliasName());
|
||||
assertEquals("field-alias_type2", fieldAlias.getType());
|
||||
assertEquals("field2", fieldAlias.getFieldName());
|
||||
|
||||
// test attribute alias
|
||||
aliases = config.getAttributeAliases();
|
||||
assertNotNull(aliases);
|
||||
assertEquals(2, aliases.size());
|
||||
|
||||
AttributeAlias attributeAlias = (AttributeAlias) aliases.get(0);
|
||||
assertEquals("attribute-alias_name1", attributeAlias.getAttributeName());
|
||||
assertEquals("attribute-alias_alias1", attributeAlias.getAlias());
|
||||
|
||||
attributeAlias = (AttributeAlias) aliases.get(1);
|
||||
assertEquals("attribute-alias_name2", attributeAlias.getAttributeName());
|
||||
assertEquals("attribute-alias_alias2", attributeAlias.getAlias());
|
||||
|
||||
// test attribute properties
|
||||
List properties = config.getAttributes();
|
||||
assertNotNull(properties);
|
||||
assertEquals(2, properties.size());
|
||||
|
||||
AttributeProperties attributeProperties = (AttributeProperties) properties.get(0);
|
||||
assertEquals("attribute-properties_type1", attributeProperties.getType());
|
||||
assertEquals("attribute-properties_field1", attributeProperties.getFieldName());
|
||||
|
||||
attributeProperties = (AttributeProperties) properties.get(1);
|
||||
assertEquals("attribute-properties_type2", attributeProperties.getType());
|
||||
assertEquals("attribute-properties_field2", attributeProperties.getFieldName());
|
||||
|
||||
// test converters
|
||||
properties = config.getConverters();
|
||||
assertNotNull(properties);
|
||||
assertEquals(2, properties.size());
|
||||
|
||||
ConverterProperties converterProperties = (ConverterProperties) properties.get(0);
|
||||
assertEquals("converter.class-name1", converterProperties.getClassName());
|
||||
assertEquals(-50, converterProperties.getPriority());
|
||||
|
||||
converterProperties = (ConverterProperties) properties.get(1);
|
||||
assertEquals("converter.class-name2", converterProperties.getClassName());
|
||||
assertEquals(750, converterProperties.getPriority());
|
||||
|
||||
// test implicit collections
|
||||
List collections = config.getImplicitCollections();
|
||||
assertNotNull(collections);
|
||||
assertEquals(2, collections.size());
|
||||
|
||||
ImplicitCollection implicitCollection = (ImplicitCollection) collections.get(0);
|
||||
assertEquals("ic_owner-type1", implicitCollection.getOwnerType());
|
||||
assertEquals("ic_field-name1", implicitCollection.getFieldName());
|
||||
assertEquals("ic_itemField-name1", implicitCollection.getItemFieldName());
|
||||
assertEquals("ic_item-type1", implicitCollection.getItemType());
|
||||
|
||||
implicitCollection = (ImplicitCollection) collections.get(1);
|
||||
assertEquals("ic_owner-type2", implicitCollection.getOwnerType());
|
||||
assertEquals("ic_field-name2", implicitCollection.getFieldName());
|
||||
assertNull(implicitCollection.getItemFieldName());
|
||||
assertEquals("ic_item-type2", implicitCollection.getItemType());
|
||||
|
||||
// test ommited fields
|
||||
List fields = config.getOmmitedFields();
|
||||
assertNotNull(fields);
|
||||
assertEquals(2, fields.size());
|
||||
|
||||
OmmitedField ommitedField = (OmmitedField) fields.get(0);
|
||||
assertEquals("ommited-field_type1", ommitedField.getType());
|
||||
assertEquals("ommited-field_field1", ommitedField.getFieldName());
|
||||
|
||||
ommitedField = (OmmitedField) fields.get(1);
|
||||
assertEquals("ommited-field_type2", ommitedField.getType());
|
||||
assertEquals("ommited-field_field2", ommitedField.getFieldName());
|
||||
|
||||
// test immutable types
|
||||
List types = config.getImmutableTypes();
|
||||
assertNotNull(types);
|
||||
assertEquals(2, types.size());
|
||||
assertEquals("immutable-type1", types.get(0));
|
||||
assertEquals("immutable-type2", types.get(1));
|
||||
|
||||
// test default implementations
|
||||
List implementations = config.getDefaultImplementations();
|
||||
assertNotNull(implementations);
|
||||
assertEquals(2, implementations.size());
|
||||
|
||||
DefaultImplementation defaultImplementation = (DefaultImplementation) implementations.get(0);
|
||||
assertEquals("default-implementation1", defaultImplementation.getDefaultImpl());
|
||||
assertEquals("type1", defaultImplementation.getType());
|
||||
|
||||
defaultImplementation = (DefaultImplementation) implementations.get(1);
|
||||
assertEquals("default-implementation2", defaultImplementation.getDefaultImpl());
|
||||
assertEquals("type2", defaultImplementation.getType());
|
||||
|
||||
// test mappings
|
||||
List mappings = config.getMappings();
|
||||
assertNotNull(mappings);
|
||||
assertEquals(2, mappings.size());
|
||||
|
||||
Mapping mapping = (Mapping) mappings.get(0);
|
||||
assertEquals("uri1", mapping.getNamespaceURI());
|
||||
assertEquals("localpart1", mapping.getLocalPart());
|
||||
assertEquals("prefix1", mapping.getPrefix());
|
||||
assertEquals("classname1", mapping.getClassName());
|
||||
|
||||
mapping = (Mapping) mappings.get(1);
|
||||
assertEquals("uri2", mapping.getNamespaceURI());
|
||||
assertEquals("localpart2", mapping.getLocalPart());
|
||||
assertEquals("prefix2", mapping.getPrefix());
|
||||
assertEquals("classname2", mapping.getClassName());
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Test getXStreamConfiguration with non-existing config file.
|
||||
* @throws Exception
|
||||
*/
|
||||
public void testNonExistingConfigFile() throws Exception {
|
||||
|
||||
// set config file to non-existing file
|
||||
factory.setConfigFile(new ClassPathResource("nonexisting-xstream-config-file.xml"));
|
||||
|
||||
// try to get XStreamConfiguration
|
||||
try {
|
||||
factory.afterPropertiesSet();
|
||||
fail("BatchEnvironmentException was expected");
|
||||
}
|
||||
catch (BatchEnvironmentException bee) {
|
||||
assertTrue(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,901 +0,0 @@
|
||||
/*
|
||||
* 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.io.xml.xstream;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.springframework.batch.io.exception.BatchEnvironmentException;
|
||||
import org.springframework.batch.io.xml.ObjectInput;
|
||||
import org.springframework.batch.io.xml.ObjectOutput;
|
||||
import org.springframework.batch.io.xml.xstream.AttributeAlias;
|
||||
import org.springframework.batch.io.xml.xstream.AttributeProperties;
|
||||
import org.springframework.batch.io.xml.xstream.ClassAlias;
|
||||
import org.springframework.batch.io.xml.xstream.DefaultImplementation;
|
||||
import org.springframework.batch.io.xml.xstream.FieldAlias;
|
||||
import org.springframework.batch.io.xml.xstream.ImplicitCollection;
|
||||
import org.springframework.batch.io.xml.xstream.OmmitedField;
|
||||
import org.springframework.batch.io.xml.xstream.TypeAlias;
|
||||
import org.springframework.batch.io.xml.xstream.XStreamConfiguration;
|
||||
import org.springframework.batch.io.xml.xstream.XStreamFactory;
|
||||
import org.springframework.core.io.FileSystemResource;
|
||||
|
||||
import com.thoughtworks.xstream.XStream;
|
||||
|
||||
/**
|
||||
* Integretion test for XStreamFactory.
|
||||
*
|
||||
* @author peter.zozom
|
||||
*/
|
||||
public class XStreamFactoryIntegrationTests extends TestCase {
|
||||
|
||||
private XStream stream;
|
||||
|
||||
private XStreamConfiguration config;
|
||||
|
||||
private XStreamFactory factory;
|
||||
|
||||
public void testAddDefaultImplementations() throws ClassNotFoundException {
|
||||
|
||||
// override tested methods
|
||||
class XStreamExt extends XStream {
|
||||
|
||||
private String diName;
|
||||
|
||||
private String otName;
|
||||
|
||||
private boolean test = false;
|
||||
|
||||
public void init(String diName, String otName) {
|
||||
test = true;
|
||||
this.diName = diName;
|
||||
this.otName = otName;
|
||||
}
|
||||
|
||||
public void addDefaultImplementation(Class defaultImplementation, Class ofType) {
|
||||
if (test) {
|
||||
assertEquals(diName, defaultImplementation.getName());
|
||||
assertEquals(otName, ofType.getName());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TEST1: test adding default implementation
|
||||
|
||||
// create new XStream
|
||||
stream = new XStreamExt();
|
||||
// set expected values
|
||||
((XStreamExt) stream).init("java.util.ArrayList", "java.util.List");
|
||||
|
||||
// create DefaultImplemetation object
|
||||
DefaultImplementation di = new DefaultImplementation();
|
||||
di.setDefaultImpl("java.util.ArrayList");
|
||||
di.setType("java.util.List");
|
||||
|
||||
// add it to list of defaultImplementations
|
||||
List defaultImplementations = new ArrayList();
|
||||
defaultImplementations.add(di);
|
||||
|
||||
// create configuration object
|
||||
config = new XStreamConfiguration();
|
||||
// set list of defaultImplementations
|
||||
config.setDefaultImplementations(defaultImplementations);
|
||||
|
||||
// create factory
|
||||
factory = new XStreamFactory();
|
||||
// set config object
|
||||
factory.setConfig(config);
|
||||
// call set-up method for XStream
|
||||
factory.setUpXStream(stream);
|
||||
|
||||
// TEST2: ClassNotFoundException for 'defaultImplementation' parameter
|
||||
|
||||
// set defaultImplementation class name to some non-existing class name
|
||||
di.setDefaultImpl("test.some.nonexisting.ClassName");
|
||||
// call set-up method for XStream - BatchEnvironmentException is
|
||||
// expected
|
||||
try {
|
||||
factory.setUpXStream(stream);
|
||||
fail("BatchEnvironmentException was expected");
|
||||
}
|
||||
catch (BatchEnvironmentException bee) {
|
||||
assertTrue(bee.getCause() instanceof ClassNotFoundException);
|
||||
}
|
||||
|
||||
// TEST3: ClassNotFoundException for 'ofType' parameter
|
||||
|
||||
// set ofType class name to some non-existing class name
|
||||
di.setType("test.some.nonexisting.ClassName");
|
||||
di.setDefaultImpl("java.util.List");
|
||||
|
||||
// call set-up method for XStream - BatchEnvironmentException is
|
||||
// expected
|
||||
try {
|
||||
factory.setUpXStream(stream);
|
||||
fail("BatchEnvironmentException was expected");
|
||||
}
|
||||
catch (BatchEnvironmentException bee) {
|
||||
assertTrue(bee.getCause() instanceof ClassNotFoundException);
|
||||
}
|
||||
}
|
||||
|
||||
public void testSetClassAliases() {
|
||||
|
||||
// override tested methods
|
||||
class XStreamExt extends XStream {
|
||||
|
||||
private String shortName;
|
||||
|
||||
private String typeName;
|
||||
|
||||
private String diName;
|
||||
|
||||
private boolean test;
|
||||
|
||||
public void init(String shortName, String typeName, String diName) {
|
||||
test = true;
|
||||
this.shortName = shortName;
|
||||
this.typeName = typeName;
|
||||
this.diName = diName;
|
||||
}
|
||||
|
||||
public void alias(String name, Class type, Class defaultImplementation) {
|
||||
if (test) {
|
||||
assertEquals(shortName, name);
|
||||
assertEquals(typeName, type.getName());
|
||||
assertEquals(diName, defaultImplementation.getName());
|
||||
}
|
||||
}
|
||||
|
||||
public void alias(String name, Class type) {
|
||||
if (test) {
|
||||
assertEquals(shortName, name);
|
||||
assertEquals(typeName, type.getName());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TEST1: test setting class alias with method alias(String,Class,Class)
|
||||
|
||||
// create new XStream
|
||||
stream = new XStreamExt();
|
||||
// set expected values
|
||||
((XStreamExt) stream).init("testAlias", "java.util.List", "java.util.ArrayList");
|
||||
|
||||
// create classAlias
|
||||
ClassAlias classAlias = new ClassAlias();
|
||||
classAlias.setName("testAlias");
|
||||
classAlias.setType("java.util.List");
|
||||
classAlias.setDefaultImplementation("java.util.ArrayList");
|
||||
|
||||
// add it to the list of aliases
|
||||
List classAliases = new ArrayList();
|
||||
classAliases.add(classAlias);
|
||||
|
||||
// create configuration object
|
||||
config = new XStreamConfiguration();
|
||||
// set list of classAliases
|
||||
config.setClassAliases(classAliases);
|
||||
|
||||
// create factory
|
||||
factory = new XStreamFactory();
|
||||
// set config object
|
||||
factory.setConfig(config);
|
||||
// call set-up method for XStream
|
||||
factory.setUpXStream(stream);
|
||||
|
||||
// TEST2: test setting class alias with method alias(String,Class)
|
||||
classAlias.setDefaultImplementation(null);
|
||||
factory.setUpXStream(stream);
|
||||
|
||||
// TEST3: ClassNotFoundException for 'defaultImplementation' parameter
|
||||
classAlias.setDefaultImplementation("test.some.nonexisting.ClassName");
|
||||
// call set-up method for XStream - BatchEnvironmentException is
|
||||
// expected
|
||||
try {
|
||||
factory.setUpXStream(stream);
|
||||
fail("BatchEnvironmentException was expected");
|
||||
}
|
||||
catch (BatchEnvironmentException bee) {
|
||||
assertTrue(bee.getCause() instanceof ClassNotFoundException);
|
||||
}
|
||||
|
||||
// TEST4: ClassNotFoundException for 'type' parameter
|
||||
classAlias.setDefaultImplementation(null);
|
||||
classAlias.setType("test.some.nonexisting.ClassName");
|
||||
// call set-up method for XStream - BatchEnvironmentException is
|
||||
// expected
|
||||
try {
|
||||
factory.setUpXStream(stream);
|
||||
fail("BatchEnvironmentException was expected");
|
||||
}
|
||||
catch (BatchEnvironmentException bee) {
|
||||
assertTrue(bee.getCause() instanceof ClassNotFoundException);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void testSetTypeAliases() {
|
||||
|
||||
// override tested methods
|
||||
class XStreamExt extends XStream {
|
||||
|
||||
private String shortName;
|
||||
|
||||
private String typeName;
|
||||
|
||||
private boolean test;
|
||||
|
||||
public void init(String shortName, String typeName) {
|
||||
test = true;
|
||||
this.shortName = shortName;
|
||||
this.typeName = typeName;
|
||||
}
|
||||
|
||||
public void aliasType(String name, Class type) {
|
||||
if (test) {
|
||||
assertEquals(shortName, name);
|
||||
assertEquals(typeName, type.getName());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TEST1: test setting type alias with method alias(String,Class)
|
||||
|
||||
// create new XStream
|
||||
stream = new XStreamExt();
|
||||
// set expected values
|
||||
((XStreamExt) stream).init("testAlias", "java.util.List");
|
||||
|
||||
// create classAlias
|
||||
TypeAlias typeAlias = new TypeAlias();
|
||||
typeAlias.setName("testAlias");
|
||||
typeAlias.setType("java.util.List");
|
||||
|
||||
// add it to the list of aliases
|
||||
List typeAliases = new ArrayList();
|
||||
typeAliases.add(typeAlias);
|
||||
|
||||
// create configuration object
|
||||
config = new XStreamConfiguration();
|
||||
// set list of classAliases
|
||||
config.setTypeAliases(typeAliases);
|
||||
|
||||
// create factory
|
||||
factory = new XStreamFactory();
|
||||
// set config object
|
||||
factory.setConfig(config);
|
||||
// call set-up method for XStream
|
||||
factory.setUpXStream(stream);
|
||||
|
||||
// TEST2: ClassNotFoundException for 'type' parameter
|
||||
typeAlias.setType("test.some.nonexisting.ClassName");
|
||||
// call set-up method for XStream - BatchEnvironmentException is
|
||||
// expected
|
||||
try {
|
||||
factory.setUpXStream(stream);
|
||||
fail("BatchEnvironmentException was expected");
|
||||
}
|
||||
catch (BatchEnvironmentException bee) {
|
||||
assertTrue(bee.getCause() instanceof ClassNotFoundException);
|
||||
}
|
||||
}
|
||||
|
||||
public void testSetFieldAliases() {
|
||||
|
||||
// override tested methods
|
||||
class XStreamExt extends XStream {
|
||||
|
||||
private String aliasName;
|
||||
|
||||
private String typeName;
|
||||
|
||||
private String fieldName;
|
||||
|
||||
private boolean test;
|
||||
|
||||
public void init(String aliasName, String typeName, String fieldName) {
|
||||
test = true;
|
||||
this.aliasName = aliasName;
|
||||
this.typeName = typeName;
|
||||
this.fieldName = fieldName;
|
||||
}
|
||||
|
||||
public void aliasField(String aliasName, Class type, String fieldName) {
|
||||
if (test) {
|
||||
assertEquals(this.aliasName, aliasName);
|
||||
assertEquals(typeName, type.getName());
|
||||
assertEquals(this.fieldName, fieldName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TEST1: test setting type alias with method alias(String,Class)
|
||||
|
||||
// create new XStream
|
||||
stream = new XStreamExt();
|
||||
// set expected values
|
||||
((XStreamExt) stream).init("testAlias", "java.util.List", "list");
|
||||
|
||||
// create classAlias
|
||||
FieldAlias fieldAlias = new FieldAlias();
|
||||
fieldAlias.setAliasName("testAlias");
|
||||
fieldAlias.setType("java.util.List");
|
||||
fieldAlias.setFieldName("list");
|
||||
|
||||
// add it to the list of aliases
|
||||
List fieldAliases = new ArrayList();
|
||||
fieldAliases.add(fieldAlias);
|
||||
|
||||
// create configuration object
|
||||
config = new XStreamConfiguration();
|
||||
// set list of classAliases
|
||||
config.setFieldAliases(fieldAliases);
|
||||
|
||||
// create factory
|
||||
factory = new XStreamFactory();
|
||||
// set config object
|
||||
factory.setConfig(config);
|
||||
// call set-up method for XStream
|
||||
factory.setUpXStream(stream);
|
||||
|
||||
// TEST2: ClassNotFoundException for 'type' parameter
|
||||
fieldAlias.setType("test.some.nonexisting.ClassName");
|
||||
// call set-up method for XStream - BatchEnvironmentException is
|
||||
// expected
|
||||
try {
|
||||
factory.setUpXStream(stream);
|
||||
fail("BatchEnvironmentException was expected");
|
||||
}
|
||||
catch (BatchEnvironmentException bee) {
|
||||
assertTrue(bee.getCause() instanceof ClassNotFoundException);
|
||||
}
|
||||
}
|
||||
|
||||
public void testSetAttributeAliases() {
|
||||
|
||||
// override tested methods
|
||||
class XStreamExt extends XStream {
|
||||
|
||||
private String alias;
|
||||
|
||||
private String attributeName;
|
||||
|
||||
private boolean test = false;
|
||||
|
||||
public void init(String alias, String attributeName) {
|
||||
test = true;
|
||||
this.alias = alias;
|
||||
this.attributeName = attributeName;
|
||||
}
|
||||
|
||||
public void aliasAttribute(String alias, String attributeName) {
|
||||
if (test) {
|
||||
assertEquals(this.alias, alias);
|
||||
assertEquals(this.attributeName, attributeName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TEST1: test adding attribute aliases
|
||||
|
||||
// create new XStream
|
||||
stream = new XStreamExt();
|
||||
// set expected values
|
||||
((XStreamExt) stream).init("alias", "attribute");
|
||||
|
||||
AttributeAlias alias = new AttributeAlias();
|
||||
alias.setAlias("alias");
|
||||
alias.setAttributeName("attribute");
|
||||
|
||||
List aliases = new ArrayList();
|
||||
aliases.add(alias);
|
||||
|
||||
// create configuration object
|
||||
config = new XStreamConfiguration();
|
||||
// set list of classAliases
|
||||
config.setAttributeAliases(aliases);
|
||||
|
||||
// create factory
|
||||
factory = new XStreamFactory();
|
||||
// set config object
|
||||
factory.setConfig(config);
|
||||
// call set-up method for XStream
|
||||
factory.setUpXStream(stream);
|
||||
}
|
||||
|
||||
public void testSetAttributes() {
|
||||
|
||||
// override tested methods
|
||||
class XStreamExt extends XStream {
|
||||
|
||||
private String type;
|
||||
|
||||
private String fieldName;
|
||||
|
||||
private boolean test = false;
|
||||
|
||||
public void init(String type, String fieldName) {
|
||||
test = true;
|
||||
this.type = type;
|
||||
this.fieldName = fieldName;
|
||||
}
|
||||
|
||||
public void useAttributeFor(Class type) {
|
||||
if (test) {
|
||||
assertEquals(this.type, type.getName());
|
||||
}
|
||||
}
|
||||
|
||||
public void useAttributeFor(String fieldName, Class type) {
|
||||
if (test) {
|
||||
assertEquals(this.fieldName, fieldName);
|
||||
assertEquals(this.type, type.getName());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TEST1: test adding attribute properties with
|
||||
// useAttributeFor(String,Class)
|
||||
|
||||
// create new XStream
|
||||
stream = new XStreamExt();
|
||||
// set expected values
|
||||
((XStreamExt) stream).init("java.util.List", "fieldName");
|
||||
|
||||
AttributeProperties props = new AttributeProperties();
|
||||
props.setFieldName("fieldName");
|
||||
props.setType("java.util.List");
|
||||
|
||||
List properties = new ArrayList();
|
||||
properties.add(props);
|
||||
|
||||
// create configuration object
|
||||
config = new XStreamConfiguration();
|
||||
// set list of classAliases
|
||||
config.setAttributes(properties);
|
||||
|
||||
// create factory
|
||||
factory = new XStreamFactory();
|
||||
// set config object
|
||||
factory.setConfig(config);
|
||||
// call set-up method for XStream
|
||||
factory.setUpXStream(stream);
|
||||
|
||||
// TEST2: test adding attribute properties with useAttributeFor(String)
|
||||
props.setFieldName(null);
|
||||
factory.setUpXStream(stream);
|
||||
|
||||
// TEST3: ClassNotFoundException for 'type' parameter
|
||||
props.setType("test.some.nonexisting.ClassName");
|
||||
// call set-up method for XStream - BatchEnvironmentException is
|
||||
// expected
|
||||
try {
|
||||
factory.setUpXStream(stream);
|
||||
fail("BatchEnvironmentException was expected");
|
||||
}
|
||||
catch (BatchEnvironmentException bee) {
|
||||
assertTrue(bee.getCause() instanceof ClassNotFoundException);
|
||||
}
|
||||
}
|
||||
|
||||
// TODO different results for JDK1.4 and JDK1.5
|
||||
// public void testRegisterConverters() {
|
||||
//
|
||||
// // override tested methods
|
||||
// class XStreamExt extends XStream {
|
||||
//
|
||||
// private String className;
|
||||
//
|
||||
// private int priority;
|
||||
//
|
||||
// private boolean test = false;
|
||||
//
|
||||
// public void init(String className, int priority) {
|
||||
// test = true;
|
||||
// this.className = className;
|
||||
// this.priority = priority;
|
||||
// }
|
||||
//
|
||||
// public void registerConverter(Converter converter, int priority) {
|
||||
// if (test) {
|
||||
// assertEquals(className, converter.getClass().getName());
|
||||
// assertEquals(this.priority, priority);
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// public void registerConverter(SingleValueConverter converter, int priority) {
|
||||
// if (test) {
|
||||
// assertEquals(className, converter.getClass().getName());
|
||||
// assertEquals(this.priority, priority);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// // TEST1: test registering single value converter
|
||||
//
|
||||
// // create new XStream
|
||||
// stream = new XStreamExt();
|
||||
// // set expected values
|
||||
// ((XStreamExt) stream).init("com.thoughtworks.xstream.converters.basic.FloatConverter", 10);
|
||||
//
|
||||
// ConverterProperties cp = new ConverterProperties();
|
||||
// cp.setConverterClassName("com.thoughtworks.xstream.converters.basic.FloatConverter");
|
||||
// cp.setPriority(10);
|
||||
//
|
||||
// List converters = new ArrayList();
|
||||
// converters.add(cp);
|
||||
//
|
||||
// // create configuration object
|
||||
// config = new XStreamConfiguration();
|
||||
// // set list of classAliases
|
||||
// config.setConverters(converters);
|
||||
//
|
||||
// // create factory
|
||||
// factory = new XStreamFactory();
|
||||
// // set config object
|
||||
// factory.setConfig(config);
|
||||
// // call set-up method for XStream
|
||||
// factory.setUpXStream(stream);
|
||||
//
|
||||
// // TEST2: test registering converter
|
||||
// cp.setConverterClassName("com.thoughtworks.xstream.converters.basic.NullConverter");
|
||||
// ((XStreamExt) stream).init("com.thoughtworks.xstream.converters.basic.NullConverter", 10);
|
||||
// factory.setUpXStream(stream);
|
||||
//
|
||||
// // TEST3: BatchEnviromentException due to invalid type (not assignable
|
||||
// // to SingleValueConverter or Converter)
|
||||
// cp.setConverterClassName("java.util.List");
|
||||
// try {
|
||||
// factory.setUpXStream(stream);
|
||||
// fail("BatchEnvironmentException was expected");
|
||||
// }
|
||||
// catch (BatchEnvironmentException bee) {
|
||||
// assertNull(bee.getCause());
|
||||
// }
|
||||
//
|
||||
// // TEST4: ClassNotFoundException
|
||||
// cp.setConverterClassName("test.some.nonexisting.ClassName");
|
||||
// try {
|
||||
// factory.setUpXStream(stream);
|
||||
// fail("BatchEnvironmentException was expected");
|
||||
// }
|
||||
// catch (BatchEnvironmentException bee) {
|
||||
// assertTrue(bee.getCause() instanceof ClassNotFoundException);
|
||||
// }
|
||||
//
|
||||
// // TEST5: InstantiationException
|
||||
// // set interface as className
|
||||
// cp.setConverterClassName("com.thoughtworks.xstream.converters.Converter");
|
||||
// try {
|
||||
// factory.setUpXStream(stream);
|
||||
// fail("BatchEnvironmentException was expected");
|
||||
// }
|
||||
// catch (BatchEnvironmentException bee) {
|
||||
// assertTrue(bee.getCause() instanceof InstantiationException);
|
||||
// }
|
||||
// }
|
||||
|
||||
public void testSetMode() {
|
||||
|
||||
// override tested methods
|
||||
class XStreamExt extends XStream {
|
||||
|
||||
private int mode;
|
||||
|
||||
private boolean test = false;
|
||||
|
||||
public void init(int mode) {
|
||||
test = true;
|
||||
this.mode = mode;
|
||||
}
|
||||
|
||||
public void setMode(int mode) {
|
||||
if (test) {
|
||||
assertEquals(this.mode, mode);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// create new XStream
|
||||
stream = new XStreamExt();
|
||||
((XStreamExt) stream).init(1001);
|
||||
|
||||
// create configuration object
|
||||
config = new XStreamConfiguration();
|
||||
// set list of classAliases
|
||||
config.setMode(1001);
|
||||
|
||||
// create factory
|
||||
factory = new XStreamFactory();
|
||||
// set config object
|
||||
factory.setConfig(config);
|
||||
// call set-up method for XStream
|
||||
factory.setUpXStream(stream);
|
||||
}
|
||||
|
||||
public void testAddImplicitCollections() {
|
||||
|
||||
// override tested methods
|
||||
class XStreamExt extends XStream {
|
||||
|
||||
private String ownerType;
|
||||
|
||||
private String fieldName;
|
||||
|
||||
private String itemFieldName;
|
||||
|
||||
private String itemType;
|
||||
|
||||
private boolean test = false;
|
||||
|
||||
/*
|
||||
* Set expected values
|
||||
*/
|
||||
public void init(String ownerType, String fieldName, String itemFieldName, String itemType) {
|
||||
test = true;
|
||||
this.ownerType = ownerType;
|
||||
this.fieldName = fieldName;
|
||||
this.itemFieldName = itemFieldName;
|
||||
this.itemType = itemType;
|
||||
}
|
||||
|
||||
public void addImplicitCollection(Class ownerType, String fieldName, Class itemType) {
|
||||
if (test) {
|
||||
assertEquals(this.ownerType, ownerType.getName());
|
||||
assertEquals(this.fieldName, fieldName);
|
||||
assertEquals(this.itemType, itemType.getName());
|
||||
}
|
||||
}
|
||||
|
||||
public void addImplicitCollection(Class ownerType, String fieldName, String itemFieldName, Class itemType) {
|
||||
if (test) {
|
||||
assertEquals(this.ownerType, ownerType.getName());
|
||||
assertEquals(this.fieldName, fieldName);
|
||||
assertEquals(this.itemFieldName, itemFieldName);
|
||||
assertEquals(this.itemType, itemType.getName());
|
||||
}
|
||||
}
|
||||
|
||||
public void addImplicitCollection(Class ownerType, String fieldName) {
|
||||
if (test) {
|
||||
assertEquals(this.ownerType, ownerType.getName());
|
||||
assertEquals(this.fieldName, fieldName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// create new XStream
|
||||
stream = new XStreamExt();
|
||||
((XStreamExt) stream).init("java.util.List", "fieldName", "itemFieldName", "java.util.Map");
|
||||
|
||||
// TEST1: test adding implicit collection with
|
||||
// addImplicitCollection(Class, String)
|
||||
ImplicitCollection implicitCollection = new ImplicitCollection();
|
||||
implicitCollection.setOwnerType("java.util.List");
|
||||
implicitCollection.setFieldName("fieldName");
|
||||
|
||||
List implicitCollections = new ArrayList();
|
||||
implicitCollections.add(implicitCollection);
|
||||
|
||||
// create configuration object
|
||||
config = new XStreamConfiguration();
|
||||
// set list of classAliases
|
||||
config.setImplicitCollections(implicitCollections);
|
||||
|
||||
// create factory
|
||||
factory = new XStreamFactory();
|
||||
// set config object
|
||||
factory.setConfig(config);
|
||||
// call set-up method for XStream
|
||||
factory.setUpXStream(stream);
|
||||
|
||||
// TEST2: test adding implicit collection with
|
||||
// addImplicitCollection(Class, String, String)
|
||||
implicitCollection.setItemType("java.util.Map");
|
||||
factory.setUpXStream(stream);
|
||||
|
||||
// TEST3: test adding implicit collection with
|
||||
// addImplicitCollection(Class, String, String, String)
|
||||
implicitCollection.setItemFieldName("itemFieldName");
|
||||
factory.setUpXStream(stream);
|
||||
|
||||
// TEST4: ClassNotFoundException due to non-existing class name in
|
||||
// itemType
|
||||
implicitCollection.setItemType("test.some.nonexisting.ClassName");
|
||||
try {
|
||||
factory.setUpXStream(stream);
|
||||
fail("BatchEnvironmentException was expected");
|
||||
}
|
||||
catch (BatchEnvironmentException bee) {
|
||||
assertTrue(bee.getCause() instanceof ClassNotFoundException);
|
||||
}
|
||||
|
||||
// TEST5: ClassNotFoundException due to non-existing class name in
|
||||
// ownerType
|
||||
implicitCollection.setOwnerType("test.some.nonexisting.ClassName");
|
||||
try {
|
||||
factory.setUpXStream(stream);
|
||||
fail("BatchEnvironmentException was expected");
|
||||
}
|
||||
catch (BatchEnvironmentException bee) {
|
||||
assertTrue(bee.getCause() instanceof ClassNotFoundException);
|
||||
}
|
||||
}
|
||||
|
||||
public void testSetOmittedFields() {
|
||||
|
||||
// override tested methods
|
||||
class XStreamExt extends XStream {
|
||||
|
||||
private String type;
|
||||
|
||||
private String fieldName;
|
||||
|
||||
private boolean test = false;
|
||||
|
||||
public void init(String type, String fieldName) {
|
||||
test = true;
|
||||
this.type = type;
|
||||
this.fieldName = fieldName;
|
||||
}
|
||||
|
||||
public void omitField(Class type, String fieldName) {
|
||||
if (test) {
|
||||
assertEquals(this.type, type.getName());
|
||||
assertEquals(this.fieldName, fieldName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TEST1: test adding ommited fields
|
||||
|
||||
// create new XStream
|
||||
stream = new XStreamExt();
|
||||
// set expected values
|
||||
((XStreamExt) stream).init("java.util.List", "fieldName");
|
||||
|
||||
OmmitedField ommitedField = new OmmitedField();
|
||||
ommitedField.setType("java.util.List");
|
||||
ommitedField.setFieldName("fieldName");
|
||||
|
||||
List ommitedFields = new ArrayList();
|
||||
ommitedFields.add(ommitedField);
|
||||
|
||||
// create configuration object
|
||||
config = new XStreamConfiguration();
|
||||
// set list of classAliases
|
||||
config.setOmmitedFields(ommitedFields);
|
||||
|
||||
// create factory
|
||||
factory = new XStreamFactory();
|
||||
// set config object
|
||||
factory.setConfig(config);
|
||||
// call set-up method for XStream
|
||||
factory.setUpXStream(stream);
|
||||
|
||||
// TEST2: ClassNotFoundException
|
||||
ommitedField.setType("test.some.nonexisting.ClassName");
|
||||
try {
|
||||
factory.setUpXStream(stream);
|
||||
fail("BatchEnvironmentException was expected");
|
||||
}
|
||||
catch (BatchEnvironmentException bee) {
|
||||
assertTrue(bee.getCause() instanceof ClassNotFoundException);
|
||||
}
|
||||
}
|
||||
|
||||
public void testAddImmutableTypes() {
|
||||
|
||||
// override tested methods
|
||||
class XStreamExt extends XStream {
|
||||
|
||||
private String type;
|
||||
|
||||
private boolean test = false;
|
||||
|
||||
public void init(String type) {
|
||||
test = true;
|
||||
this.type = type;
|
||||
|
||||
}
|
||||
|
||||
public void addImmutableType(Class type) {
|
||||
if (test) {
|
||||
assertEquals(this.type, type.getName());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// create new XStream
|
||||
stream = new XStreamExt();
|
||||
// set expected values
|
||||
((XStreamExt) stream).init("java.util.List");
|
||||
|
||||
List immutableTypes = new ArrayList();
|
||||
immutableTypes.add("java.util.List");
|
||||
|
||||
// create configuration object
|
||||
config = new XStreamConfiguration();
|
||||
// set list of classAliases
|
||||
config.setImmutableTypes(immutableTypes);
|
||||
|
||||
// create factory
|
||||
factory = new XStreamFactory();
|
||||
// set config object
|
||||
factory.setConfig(config);
|
||||
// call set-up method for XStream
|
||||
factory.setUpXStream(stream);
|
||||
|
||||
// TEST2: ClassNotFoundException
|
||||
immutableTypes.clear();
|
||||
immutableTypes.add("test.some.nonexisting.ClassName");
|
||||
try {
|
||||
factory.setUpXStream(stream);
|
||||
fail("BatchEnvironmentException was expected");
|
||||
}
|
||||
catch (BatchEnvironmentException bee) {
|
||||
assertTrue(bee.getCause() instanceof ClassNotFoundException);
|
||||
}
|
||||
}
|
||||
|
||||
public void testWriteAndRead() throws IOException, ClassNotFoundException {
|
||||
|
||||
// create file
|
||||
File file = File.createTempFile("test", ".xml");
|
||||
// create factory and set empty configuration
|
||||
XStreamFactory factory = new XStreamFactory();
|
||||
factory.setConfig(new XStreamConfiguration());
|
||||
|
||||
// define test class
|
||||
class TestValueObject {
|
||||
String param1;
|
||||
|
||||
int param2;
|
||||
|
||||
Long param3;
|
||||
}
|
||||
|
||||
TestValueObject valueObject = new TestValueObject();
|
||||
valueObject.param1 = "test";
|
||||
valueObject.param2 = 392;
|
||||
valueObject.param3 = new Long(632);
|
||||
|
||||
// just a simple test for object output and input: write object to XML
|
||||
// and read it back
|
||||
|
||||
ObjectOutput output = factory.createObjectOutput(new FileSystemResource(file), "UTF-8");
|
||||
output.writeObject(valueObject);
|
||||
output.close();
|
||||
|
||||
ObjectInput input = factory.createObjectInput(new FileSystemResource(file), "UTF-8");
|
||||
Object result = input.readObject();
|
||||
input.close();
|
||||
file.delete();
|
||||
|
||||
// is result instance of TestValueObject?
|
||||
assertTrue(result instanceof TestValueObject);
|
||||
// is result equal to written object?
|
||||
assertEquals(valueObject.param1, ((TestValueObject) result).param1);
|
||||
assertEquals(valueObject.param2, ((TestValueObject) result).param2);
|
||||
assertEquals(valueObject.param3, ((TestValueObject) result).param3);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user