/*
* ModeShape (http://www.modeshape.org)
*
* 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.modeshape.sequencer.wsdl;
import java.io.IOException;
import java.io.InputStream;
import java.io.Reader;
import java.util.concurrent.atomic.AtomicLong;
import javax.jcr.Node;
import org.modeshape.common.annotation.NotThreadSafe;
import org.modeshape.common.util.SizeMeasuringInputStream;
import org.modeshape.common.util.SizeMeasuringReader;
import org.modeshape.jcr.api.sequencer.Sequencer;
import org.modeshape.sequencer.sramp.AbstractResolvingReader;
import org.xml.sax.InputSource;
/**
* A class that can parse WSDL definitions and derive a node structure from the content.
* <p>
* This class is intended to be subclassed by supplying implementations for the {@link #parse(org.xml.sax.InputSource)}.
* </p>
*
* @param <T> the type of object returned by the parser
*/
@NotThreadSafe
public abstract class WsdlReader<T> extends AbstractResolvingReader {
/**
* the URI of the document being read; never null or empty
*/
protected final String baseUri;
public WsdlReader( Sequencer.Context context,
String baseUri ) {
super(context);
this.baseUri = baseUri;
}
@Override
public void read( InputSource source,
Node outputNode ) throws Exception {
logger.debug("Processing XSD '{0}'", outputNode.getName());
Reader reader = null;
InputStream stream = null;
try {
AtomicLong contentSize = new AtomicLong();
if (source.getCharacterStream() != null) {
reader = new SizeMeasuringReader(source.getCharacterStream(), contentSize);
source = new InputSource(reader);
} else {
stream = new SizeMeasuringInputStream(source.getByteStream(), contentSize);
source = new InputSource(stream);
}
// Parse the WSDL, measuring the number of bytes as we read ...
T result = parse(source);
// Convert the WSDL to content ...
process(result, outputNode, contentSize.get());
} finally {
assert (reader != null) || (stream != null);
if (reader != null) {
try {
reader.close();
} catch (IOException e) {
logger.debug("Cannot close reader ", e);
}
}
if (stream != null) {
try {
stream.close();
} catch (IOException e) {
logger.debug("Cannot close stream ", e);
}
}
}
}
/**
* Parse the supplied source (which contains either a {@link java.io.Reader} or an {@link java.io.InputStream}) and produce a representation
* of the WSDL definition.
*
* @param source the source containing the WSDL stream; never null
* @return the WSDL definition representation; may not be null
* @throws Exception if there is a problem during parsing
*/
protected abstract T parse( InputSource source ) throws Exception;
/**
* Process the supplied representation of the WSDL definition that was returned from the {@link #parse(org.xml.sax.InputSource)}
* method and write the derived output content under the {@link Node outputNode}.
*
* @param parsedForm the representation of the WSDL definition, which will always be the value returned from
* {@link #parse(org.xml.sax.InputSource)}
* @param outputNode the {@link javax.jcr.Node node} under which the derived content for the XSD should be written; may not be null
* @param sizeOfFile the size of the WSDL stream, in bytes
* @throws Exception if there is a problem during processing
*/
protected abstract void process( T parsedForm,
Node outputNode,
long sizeOfFile ) throws Exception;
}