OpenSPCoop2MessageSoapStreamReader.java
- /*
- * GovWay - A customizable API Gateway
- * https://govway.org
- *
- * Copyright (c) 2005-2025 Link.it srl (https://link.it).
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 3, as published by
- * the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
- */
- package org.openspcoop2.message.soap.reader;
- import java.io.ByteArrayInputStream;
- import java.io.ByteArrayOutputStream;
- import java.io.InputStream;
- import java.io.OutputStream;
- import java.io.SequenceInputStream;
- import javax.xml.parsers.SAXParser;
- import javax.xml.parsers.SAXParserFactory;
- import javax.xml.soap.MimeHeaders;
- import javax.xml.soap.SOAPBody;
- import javax.xml.soap.SOAPHeader;
- import org.apache.commons.lang.StringUtils;
- import org.openspcoop2.message.OpenSPCoop2Message;
- import org.openspcoop2.message.OpenSPCoop2MessageFactory;
- import org.openspcoop2.message.constants.Costanti;
- import org.openspcoop2.message.constants.MessageType;
- import org.openspcoop2.message.exception.MessageException;
- import org.openspcoop2.message.soap.OpenSPCoop2Message_saaj_11_impl;
- import org.openspcoop2.message.soap.OpenSPCoop2Message_saaj_12_impl;
- import org.openspcoop2.message.soap.SoapUtils;
- import org.openspcoop2.utils.Utilities;
- import org.openspcoop2.utils.resources.Charset;
- import org.openspcoop2.utils.transport.http.ContentTypeUtilities;
- import org.openspcoop2.utils.transport.http.HttpConstants;
- import org.openspcoop2.utils.xml.TransformerConfig;
- import org.openspcoop2.utils.xml.XMLUtils;
- import org.w3c.dom.Node;
- import org.xml.sax.InputSource;
- import org.xml.sax.XMLReader;
- /**
- * OpenSPCoop2MessageSoapParser
- *
- * @author Andrea Poli (poli@link.it)
- * @author $Author$
- * @version $Rev$, $Date$
- */
- public class OpenSPCoop2MessageSoapStreamReader {
- public static boolean SOAP_HEADER_OPTIMIZATION_ENABLED = true;
-
- @SuppressWarnings("unused")
- private OpenSPCoop2MessageFactory msgFactory;
- private InputStream is;
- private String contentType;
- private int bufferThresholdKb;
-
- public OpenSPCoop2MessageSoapStreamReader(OpenSPCoop2MessageFactory msgFactory, String contentType, InputStream is, int bufferThresholdKb) {
- this.msgFactory = msgFactory;
- this.contentType = contentType;
- this.is = is;
- this.bufferThresholdKb = bufferThresholdKb;
- }
- private String envelope;
- private String prefixEnvelope = null;
- private String namespace;
-
- private String header;
- private String prefixHeader = null;
- private OpenSPCoop2Message _headerMsgCompleto;
- private boolean soapHeaderModified = false;
-
- private boolean soapHeaderOptimizable = false;
- private long startHeaderOffset;
- private long endHeaderOffset;
- private long startBodyOffset;
- private String isCharset;
-
- private String body;
- private boolean bodyEmpty;
- //private Element rootElement;
- private String rootElementNamespace;
- private String rootElementLocalName;
- private String rootElementPrefix;
- private String fault;
-
- private int bufferSize;
-
- private boolean parsingComplete = false;
-
- private MessageException tBuffered = null;
-
- public void checkException() throws MessageException {
- if(this.tBuffered!=null) {
- throw this.tBuffered;
- }
- }
- private InputStream bufferedInputStream = null;
- public InputStream getBufferedInputStream() {
- return this.bufferedInputStream;
- }
- public void releaseBufferedInputStream() {
- this.bufferedInputStream = null;
- }
- public void read() throws MessageException {
- this.bufferedInputStream = this.is;
-
- if(this.tBuffered!=null) {
- throw this.tBuffered;
- }
-
- if(this.contentType==null || StringUtils.isEmpty(this.contentType) || this.is == null) {
- return;
- }
- boolean multipart = false;
- try {
- multipart = ContentTypeUtilities.isMultipartType(this.contentType);
- }catch(Throwable t) {}
- String charset = null;
- try {
- if(!multipart) {
- charset = ContentTypeUtilities.readCharsetFromContentType(this.contentType);
- this.isCharset = charset;
- if(Charset.UTF_8.getValue().equalsIgnoreCase(charset)) {
- charset = null;
- }
- }
- else {
- String internalCT = ContentTypeUtilities.getInternalMultipartContentType(this.contentType);
- this.isCharset = ContentTypeUtilities.readCharsetFromContentType(internalCT);
- }
- }catch(Throwable t) {}
-
- try {
- ByteArrayOutputStream bufferReaded = new ByteArrayOutputStream();
- int lettiBuffer = 0;
-
- StringBuilder sbActual = null;
- long sbActualOffsetStart = -1;
- byte[] bufferRaw = new byte[1024];
- long bLetti = 0;
- int letturaPrecedente = 0;
- int kbLetti = 0;
-
- boolean envelopeFound = false;
-
- StringBuilder headerBuilder = null;
- String headerClosure = null;
- boolean headerCompletato = false;
-
- boolean bodyFound = false;
- String prefixBody = null;
-
- StringBuilder elementAfterBodyBuilder = null;
-
- boolean cdataFound = false;
- boolean commentFound = false;
-
- boolean analisiTerminata = false;
-
- // String check = org.openspcoop2.utils.Utilities.getAsString(this.is, "UTF8");
- // System.out.println("STREAM: "+check);
- // this.is = new java.io.ByteArrayInputStream(check.getBytes());
-
- while ( (lettiBuffer=this.is.read(bufferRaw)) !=-1) {
-
- // bufferizzo (1024 byte = 1kb alla volta)
- bufferReaded.write(bufferRaw, 0, lettiBuffer);
- kbLetti++;
- if(letturaPrecedente>0) {
- bLetti = bLetti + letturaPrecedente;
- }
- letturaPrecedente = lettiBuffer;
-
- // In caso di charset differente, uso una stringa
- String bufferString = null;
- if(charset!=null) {
- ByteArrayOutputStream bufferTmp = new ByteArrayOutputStream();
- bufferTmp.write(bufferRaw, 0, lettiBuffer);
- bufferTmp.flush();
- bufferTmp.close();
- bufferString = new String(bufferTmp.toByteArray(), charset);
- lettiBuffer = bufferString.length();
- }
-
- // analizzo
- for (int i = 0; i < lettiBuffer; i++) {
- char c = bufferString!=null ? bufferString.charAt(i) : (char) bufferRaw[i];
-
- if(headerCompletato && this.endHeaderOffset<=0) {
- this.endHeaderOffset = sbActualOffsetStart;
- }
-
- if( (c == '<' || startsWithLessThan(sbActual))
- &&
- !cdataFound &&
- !commentFound) {
-
- if(sbActual!=null) {
- if(sbActual.length()>0) {
-
- // devo verificare se ho incontrato un cdata o sto continuando a leggere un header
- String sPreClosure = sbActual.toString();
- sbActual.setLength(0);
- sbActualOffsetStart = i+bLetti;
-
- if(sPreClosure.startsWith("<![CDATA[")) {
- //System.out.println("FOND CDATA! in sPreClosure");
- cdataFound=true;
- }
- else if(sPreClosure.startsWith("<!--")) {
- //System.out.println("FOND <!-- COMMENTO in sPreClosure: ["+sPreClosure+"]");
- if(!sPreClosure.endsWith("-->")){
- commentFound=true;
- }
- }
-
- if(headerClosure!=null) {
- //System.out.println("AGGIUNGO AD HEADER TESTO ["+sPreClosure+"]");
- headerBuilder.append(sPreClosure);
- }
- else if(bodyFound) {
- if(!sPreClosure.startsWith("<![CDATA[") && !sPreClosure.startsWith("<!--")) {
- //System.out.println("AGGIUNGO A BODY ["+sPreClosure+"]");
- if(elementAfterBodyBuilder!=null) {
- elementAfterBodyBuilder.append(sPreClosure);
- }
- else {
- elementAfterBodyBuilder = new StringBuilder(sPreClosure);
- }
- }
- }
-
- }
- }
- else {
- sbActual = new StringBuilder();
- sbActualOffsetStart = i+bLetti;
- }
- }
- if(sbActual!=null) {
- sbActual.append(c);
- }
- if(c == '>' || endsWithGreaterThan(sbActual)) {
-
- if(sbActual==null) {
- //NO: gli attachments potrebbero rientrare in questo caso
- if(multipart) {
- continue;
- }
- else {
- throw new Exception("Invalid content; found premature '>' character ("+bufferReaded.toString()+")");
- }
- }
-
- String s = sbActual.toString();
-
- //System.out.println("S ["+s+"]");
-
- if(cdataFound) {
- if(headerClosure!=null) {
- //System.out.println("AGGIUNGO AD HEADER CDATA ["+sbActual.toString()+"]");
- headerBuilder.append(sbActual.toString());
- }
- sbActual.setLength(0);
- sbActualOffsetStart = i+bLetti;
- //System.out.println("continuo perche CDATA... ");
- if(s.endsWith("]]>")) {
- cdataFound=false;
- //System.out.println("FOUND FINE CDATA");
- }
- continue;
- }
- if(s.startsWith("<![CDATA[")) {
- //System.out.println("FOUND CDATA!");
- cdataFound=true;
- continue;
- }
-
- if(commentFound) {
- if(headerClosure!=null) {
- //System.out.println("AGGIUNGO AD HEADER COMMENTO ["+sbActual.toString()+"]");
- headerBuilder.append(sbActual.toString());
- }
- sbActual.setLength(0);
- sbActualOffsetStart = i+bLetti;
- //System.out.println("continuo perche COMMENTO... ");
- if(s.endsWith("-->")) {
- commentFound=false;
- //System.out.println("FOUND FINE COMMENTO");
- }
- continue;
- }
- if(s.startsWith("<!--")) {
- //System.out.println("FOUND <!-- COMMENTO: ["+s+"]");
- if(s.endsWith("-->")){
- if(headerClosure!=null) {
- //System.out.println("AGGIUNGO AD HEADER COMMENTO ["+sbActual.toString()+"]");
- headerBuilder.append(sbActual.toString());
- }
- sbActual.setLength(0);
- sbActualOffsetStart = i+bLetti;
- }
- else {
- commentFound=true;
- }
- continue;
- }
-
- if(s.startsWith("<?")) {
- continue;
- }
-
- if(!envelopeFound && isOpenedElement(s,"<Envelope")) {
- this.envelope = s;
- //System.out.println("INIZIALIZZO ENVELOPE ["+s+"]");
- if(!analizyEnvelopeNamespace(this.envelope)) {
- //System.out.println("TERMINO");
- analisiTerminata=true;
- break;
- }
- envelopeFound = true;
- this.prefixEnvelope = "";
- }
- else if(!envelopeFound && isOpenedElement(s,":Envelope")) {
- String sPrefix = s.substring(0, s.indexOf(":Envelope"));
- if(sPrefix.startsWith("<") && !sPrefix.contains(" ") && sPrefix.length()>1) {
- this.envelope = s;
- //System.out.println("INIZIALIZZO ENVELOPE ["+s+"]");
- if(!analizyEnvelopeNamespace(this.envelope)) {
- //System.out.println("TERMINO");
- analisiTerminata=true;
- break;
- }
- envelopeFound = true;
- this.prefixEnvelope = sPrefix.substring(1)+":";
- }
- else {
- analisiTerminata=true;
- break;
- }
- }
- else if(envelopeFound) {
-
- if(headerClosure!=null) {
- //System.out.println("AGGIUNGO AD HEADER ["+s+"]");
- headerBuilder.append(s);
- sbActual.setLength(0);
- sbActualOffsetStart = i+bLetti;
- if(s.startsWith(headerClosure)) {
- headerClosure=null;
- headerCompletato = true;
- }
- continue;
- }
-
- if(headerBuilder==null && isOpenedElement(s,"<Header")) {
- //System.out.println("INIZIALIZZO HEADER ["+s+"]");
- //headerBuilder = new StringBuilder(s);
- headerBuilder = new StringBuilder();
- if(!s.endsWith("/>")) {
- headerClosure = "</Header";
- }
- if(bodyFound) {
- analisiTerminata=true;
- break;
- }
- else {
- this.startHeaderOffset = sbActualOffsetStart;
- this.prefixHeader = "";
- }
- }
- else if(headerBuilder==null && isOpenedElement(s,":Header")) {
- String sPrefix = s.substring(0, s.indexOf(":Header"));
- if(sPrefix.startsWith("<") && !sPrefix.contains(" ") && sPrefix.length()>1) {
- //System.out.println("INIZIALIZZO HEADER ["+s+"]");
- //headerBuilder = new StringBuilder(s);
- headerBuilder = new StringBuilder();
- if(!s.endsWith("/>")) {
- headerClosure = "</"+sPrefix.substring(1)+":"+"Header";
- }
- if(bodyFound) {
- analisiTerminata=true;
- break;
- }
- else {
- this.startHeaderOffset = sbActualOffsetStart;
- this.prefixHeader = sPrefix.substring(1)+":";
- }
- }
- else {
- analisiTerminata=true;
- break;
- }
- }
- else if(!bodyFound && isOpenedElement(s,"<Body")) {
- //System.out.println("INIZIALIZZO BODY ["+s+"]");
- this.body = s;
- bodyFound = true;
- prefixBody = "";
- if(this.startHeaderOffset<=0) {
- this.startHeaderOffset = sbActualOffsetStart;
- }
- this.startBodyOffset=sbActualOffsetStart;
- sbActual.setLength(0);
- sbActualOffsetStart = i+bLetti;
- }
- else if(!bodyFound && isOpenedElement(s,":Body")) {
- String sPrefix = s.substring(0, s.indexOf(":Body"));
- if(sPrefix.startsWith("<") && !sPrefix.contains(" ") && sPrefix.length()>1) {
- //System.out.println("INIZIALIZZO BODY ["+s+"]");
- this.body = s;
- bodyFound = true;
- prefixBody = sPrefix.substring(1)+":";
- if(this.startHeaderOffset<=0) {
- this.startHeaderOffset = sbActualOffsetStart;
- }
- this.startBodyOffset=sbActualOffsetStart;
- sbActual.setLength(0);
- sbActualOffsetStart = i+bLetti;
- }
- else {
- analisiTerminata=true;
- break;
- }
- }
- else if(bodyFound) {
- if(this.fault==null && isOpenedElement(s,"<Fault")) {
- //System.out.println("INIZIALIZZO FAULT ["+s+"]");
- this.fault = s;
- }
- else if(this.fault==null && isOpenedElement(s,":Fault")) {
- String sPrefix = s.substring(0, s.indexOf(":Fault"));
- if(sPrefix.startsWith("<") && !sPrefix.contains(" ")) {
- //System.out.println("INIZIALIZZO FAULT ["+s+"]");
- this.fault = s;
- }
- }
- else {
-
- String closeBody = "</"+prefixBody+"Body";
- String closeEnvelope = "</"+this.prefixEnvelope+"Envelope";
- if( isClosedElement(s,closeBody) || isClosedElement(s,closeEnvelope) ){
- this.parsingComplete = true;
- }
- else {
- if(!endsWithGreaterThan(s)){
- if(elementAfterBodyBuilder!=null) {
- //System.out.println("AGGIUNGO A BODY dentro ["+s+"]");
- elementAfterBodyBuilder.append(s);
- }
- else {
- //System.out.println("CREO A BODY ["+s+"]");
- elementAfterBodyBuilder = new StringBuilder(s);
- }
- }
- }
-
- analisiTerminata=true;
- break;
- }
- }
-
- }
- }
-
- }
- if(analisiTerminata) {
- break;
- }
- if(kbLetti==this.bufferThresholdKb) {
- // buffer dimensione massima raggiunta
- break;
- }
- }
-
- // svuoto
- if(sbActual!=null) {
- if(sbActual.length()>0) {
- sbActual.setLength(0);
- }
- }
-
-
- bufferReaded.flush();
- bufferReaded.close();
- if(bufferReaded.size()>0) {
- this.bufferSize = bufferReaded.size();
- ByteArrayInputStream bin = new ByteArrayInputStream(bufferReaded.toByteArray());
- if(lettiBuffer!=-1) {
- // sono uscita prima della chiusura dello stream
- this.bufferedInputStream = new SequenceInputStream(bin,this.is);
- }
- else {
- // letto tutto
- this.bufferedInputStream = bin;
- }
- }
-
-
- boolean throwException = false;
- String elementAfterBody = null;
- //System.out.println("BODY ["+elementAfterBodyBuilder+"]");
- if(elementAfterBodyBuilder!=null && elementAfterBodyBuilder.length()>0) {
- elementAfterBody = elementAfterBodyBuilder.toString();
- }
- if(elementAfterBody!=null || this.fault!=null) {
- throwException=true; // ho terminato di leggere la parte interessante del messaggio
- this.parsingComplete = true;
- }
- if(headerBuilder!=null && headerBuilder.length()>0) {
- if(this.envelope.endsWith("/>")) {
- if(throwException) {
- throw new Exception("Invalid content; found 'Header' after envelope closure '/>': ("+headerBuilder+")");
- }
- else{
- return;
- }
- }
- if(headerCompletato) {
- StringBuilder sbHeaderAnalizer = new StringBuilder();
- sbHeaderAnalizer.append(this.envelope);
- sbHeaderAnalizer.append(headerBuilder.toString());
- sbHeaderAnalizer.append("<").append(this.prefixEnvelope).append("Body/>");
- sbHeaderAnalizer.append("</").append(this.prefixEnvelope).append("Envelope>");
- this.header = sbHeaderAnalizer.toString();
- }
- }
- if(this.body!=null) {
- //System.out.println("BODY ["+this.body+"]");
- if(this.envelope.endsWith("/>")) {
- if(throwException) {
- throw new Exception("Invalid content; found 'Body' after envelope closure '/>': ("+this.body+")");
- }
- else{
- return;
- }
- }
- if(this.body.endsWith("/>")) {
- this.bodyEmpty = true;
- }
- }
-
- if(this.fault!=null) {
- //System.out.println("TROVATO FAULT ["+this.fault+"]");
- if(this.body.endsWith("/>")) {
- if(throwException) {
- throw new Exception("Invalid content; found Fault after body closure '/>': ("+this.fault+")");
- }
- else{
- return;
- }
- }
- StringBuilder sbFaultAnalizer = new StringBuilder();
- sbFaultAnalizer.append(this.envelope);
- sbFaultAnalizer.append(this.body);
- sbFaultAnalizer.append(this.fault);
- if((this.fault.contains("<") && this.fault.contains(">")) && !this.fault.trim().endsWith("/>")) {
- //System.out.println("CALCOLO!! ["+this.fault+"]");
- int i = 0;
- for (; i < this.fault.length(); i++) {
- char c = this.fault.charAt(i);
- if(c=='<') {
- i++;
- break;
- }
- }
- //System.out.println("DOPO GIRO: "+i);
- StringBuilder sb = new StringBuilder();
- for (; i < this.fault.length(); i++) {
- char c = this.fault.charAt(i);
- if(c==' ' || c=='>' || c=='\t' || c=='\r' || c=='\n') {
- break;
- }
- sb.append(c);
- }
- sbFaultAnalizer.append("</").append(sb.toString()).append(">");
- //System.out.println("TROVATO:["+sb.toString()+"]");
- }
-
- sbFaultAnalizer.append("</").append(prefixBody).append("Body>");
- sbFaultAnalizer.append("</").append(this.prefixEnvelope).append("Envelope>");
- //Element e = null;
- String namespaceFaultTrovato = null;
- try {
- OpenSPCoop2Message msg = buildOp2Message(sbFaultAnalizer.toString().getBytes(), this.getMessageType());
- SOAPBody soapBody = msg.castAsSoap().getSOAPBody();
- if(soapBody!=null) {
- if(soapBody.hasFault()) {
- namespaceFaultTrovato = soapBody.getFault().getNamespaceURI();
- }
- }
- }catch(Throwable t) {
- if(throwException) {
- throw new Exception("Invalid content ("+sbFaultAnalizer.toString()+"): "+t.getMessage(),t);
- }
- else{
- return;
- }
- }
- if(!this.namespace.equals(namespaceFaultTrovato)) {
- elementAfterBody = this.fault;
- this.fault = null; // si tratta di un contenuto applicativo con nome Fault
- }
- }
-
-
- if(this.fault==null && elementAfterBody!=null) {
- //System.out.println("elementAfterBody ["+elementAfterBody+"]");
- StringBuilder sbElementAnalizer = new StringBuilder();
- sbElementAnalizer.append(this.envelope);
- sbElementAnalizer.append(this.body);
- sbElementAnalizer.append(elementAfterBody);
- if((elementAfterBody.contains("<") && elementAfterBody.contains(">")) && !elementAfterBody.trim().endsWith("/>")) {
- //System.out.println("CALCOLO!! ["+elementAfterBody+"]");
- int i = 0;
- for (; i < elementAfterBody.length(); i++) {
- char c = elementAfterBody.charAt(i);
- if(c=='<') {
- i++;
- break;
- }
- }
- //System.out.println("DOPO GIRO: "+i);
- StringBuilder sb = new StringBuilder();
- for (; i < elementAfterBody.length(); i++) {
- char c = elementAfterBody.charAt(i);
- if(c==' ' || c=='>' || c=='\t' || c=='\r' || c=='\n') {
- break;
- }
- sb.append(c);
- }
- sbElementAnalizer.append("</").append(sb.toString()).append(">");
- //System.out.println("TROVATO:["+sb.toString()+"]");
- }
- else {
- //System.out.println("RIPULISCO");
- boolean empty = true;
- for (int i = 0; i < elementAfterBody.length(); i++) {
- char c = elementAfterBody.charAt(i);
- if(c!=' ' && c!='\t' && c!='\r' && c!='\n') {
- empty = false;
- break;
- }
- }
- //System.out.println("RIPULISCO EMPTY: "+empty);
- if(empty) {
- this.bodyEmpty=true;
- }
- }
-
- //System.out.println("BODY ["+this.body+"]");
- if(this.body!=null && this.body.endsWith("/>")) {
- if(!this.bodyEmpty) {
- if(throwException) {
- throw new Exception("Invalid content; found element after body closure '/>': ("+elementAfterBody+")");
- }
- else{
- return;
- }
- }
- }
- else {
-
- sbElementAnalizer.append("</").append(prefixBody).append("Body>");
- sbElementAnalizer.append("</").append(this.prefixEnvelope).append("Envelope>");
- //System.out.println("UTILIZZO:["+sbElementAnalizer.toString()+"]");
- //Element e = null;
- SAXParser saxParser = null;
- try {
- //e = XMLUtils.getInstance().newElement(sbElementAnalizer.toString().getBytes());
-
- saxParser = getParser();
- XMLReader xmlReader = saxParser.getXMLReader();
- RootElementSaxContentHandler saxHandler = new RootElementSaxContentHandler(this.namespace);
- xmlReader.setContentHandler(saxHandler);
- //System.out.println("ANALIZZO '"+sbElementAnalizer.toString()+"'");
- try(ByteArrayInputStream bin = new ByteArrayInputStream(sbElementAnalizer.toString().getBytes())){
- InputSource inputSource = new InputSource(bin);
- xmlReader.parse(inputSource);
- }
- this.rootElementLocalName = saxHandler.getLocalName();
- this.rootElementNamespace = saxHandler.getNamespace();
- this.rootElementPrefix = saxHandler.getPrefix();
- }catch(Throwable t) {
- if(throwException) {
- throw new Exception("Invalid content '"+elementAfterBody+"' ("+sbElementAnalizer.toString()+"): "+t.getMessage(),t);
- }
- else{
- return;
- }
- }finally {
- if(saxParser!=null) {
- returnParser(saxParser);
- }
- }
- // Node body = SoapUtils.getFirstNotEmptyChildNode(this.msgFactory, e, false);
- // if(body!=null) {
- // Node element = SoapUtils.getFirstNotEmptyChildNode(this.msgFactory, body, false);
- // if(element instanceof Element) {
- // this.rootElement = (Element) element;
- // }
- // }
- }
-
- }
-
- if(this.fault==null && elementAfterBody==null) {
- if(this.parsingComplete) { // siamo arrivato alla chiusura del body o dell'envelope
- this.bodyEmpty=true;
- }
- }
-
-
- //System.out.println("parsingComplete["+this.parsingComplete+"] charset["+charset+"] startHeaderOffset["+this.startHeaderOffset+"] < endHeaderOffset["+this.endHeaderOffset+"] < startBodyOffset["+this.startBodyOffset+"]");
- if(this.parsingComplete) {
- if(charset==null || !charset.startsWith("UTF-16")) {
- if(this.startHeaderOffset>0 && this.startBodyOffset>=this.startHeaderOffset) {
- this.soapHeaderOptimizable = true;
- if(this.endHeaderOffset>0) {
- if(this.endHeaderOffset<this.startHeaderOffset || this.endHeaderOffset>this.startBodyOffset) {
- // inconsistenza
- this.soapHeaderOptimizable = false;
- }
- }
- }
- }
- }
-
- }catch(Throwable t) {
- this.tBuffered = new MessageException(t.getMessage(),t);
- throw this.tBuffered;
- }
-
- return;
-
- }
- private boolean endsWithGreaterThan( String s ) {
- if ( s == null || s.length() < 4 )
- return false;
- int startIx = s.length() - 4;
- return ( s.charAt(startIx) == '&' && s.charAt(startIx + 1) == 'g' && s.charAt(startIx + 2) == 't' && s.charAt(startIx + 3) == ';' );
- }
- private boolean endsWithGreaterThan( StringBuilder buffer ) {
- if ( buffer == null || buffer.length() < 4 )
- return false;
- int startIx = buffer.length() - 4;
- return ( buffer.charAt(startIx) == '&' && buffer.charAt(startIx + 1) == 'g' && buffer.charAt(startIx + 2) == 't' && buffer.charAt(startIx + 3) == ';' );
- }
- private boolean startsWithLessThan( StringBuilder buffer ) {
- if ( buffer == null || buffer.length() < 4 )
- return false;
- return ( buffer.charAt(0) == '&' && buffer.charAt(1) == 'l' && buffer.charAt(2) == 't' && buffer.charAt(3) == ';' );
- }
-
- private boolean isOpenedElement(String s, String prefix) {
- if(prefix.startsWith(":")) {
- return s.contains(prefix+" ") || s.contains(prefix+">") || s.contains(prefix+"/") ||
- s.contains(prefix+"\n") || s.contains(prefix+"\r") || s.contains(prefix+"\t");
- }
- else {
- return s.startsWith(prefix+" ") || s.startsWith(prefix+">") || s.startsWith(prefix+"/") ||
- s.startsWith(prefix+"\n") || s.startsWith(prefix+"\r") || s.startsWith(prefix+"\t");
- }
- }
- private boolean isClosedElement(String s, String prefix) {
- return s.startsWith(prefix+" ") || s.startsWith(prefix+">") ||
- s.startsWith(prefix+"\n") || s.startsWith(prefix+"\r") || s.startsWith(prefix+"\t");
- }
-
- private boolean analizyEnvelopeNamespace(String envelope) throws Exception {
- if(envelope!=null) {
- String s = null;
- if(envelope.endsWith("/>")) {
- s = envelope;
- }
- else {
- s = envelope.replace(">", "/>");
- }
-
- //Element e = XMLUtils.getInstance().newElement(s.getBytes());
- //this.namespace = e.getNamespaceURI();
- //System.out.println("ENVELOPE PARSE ["+envelope+"]");
- SAXParser saxParser = null;
- try {
- saxParser = getParser();
- XMLReader xmlReader = saxParser.getXMLReader();
- SoapEnvelopeSaxContentHandler saxHandler = new SoapEnvelopeSaxContentHandler();
- xmlReader.setContentHandler(saxHandler);
- try(ByteArrayInputStream bin = new ByteArrayInputStream(s.getBytes())){
- InputSource inputSource = new InputSource(bin);
- xmlReader.parse(inputSource);
- }
- this.namespace = saxHandler.getNamespace();
- //System.out.println("ENVELOPE PARSE ["+envelope+"], found namespace: "+this.namespace);
- }
- catch(Throwable t) {
- throw new Exception("Invalid content ("+s+"): "+t.getMessage(),t);
- }
- finally {
- if(saxParser!=null) {
- returnParser(saxParser);
- }
- }
-
-
- return Costanti.SOAP_ENVELOPE_NAMESPACE.equals(this.namespace) ||
- Costanti.SOAP12_ENVELOPE_NAMESPACE.equals(this.namespace);
- }
- return false;
- }
- public String getEnvelope() {
- return this.envelope;
- }
- public String getNamespace() {
- return this.namespace;
- }
-
- public MessageType getMessageType() {
- if(Costanti.SOAP_ENVELOPE_NAMESPACE.equals(this.namespace)) {
- return MessageType.SOAP_11;
- }
- else {
- return MessageType.SOAP_12;
- }
- }
- public boolean isParsingComplete() {
- return this.parsingComplete;
- }
-
- // public String getBody() {
- // return this.body;
- // }
- public boolean isFault() {
- return this.fault!=null;
- }
-
- public boolean isEmpty() {
- return this.bodyEmpty;
- }
-
- public int getBufferSize() {
- return this.bufferSize;
- }
-
- public OpenSPCoop2Message getHeader_OpenSPCoop2Message() throws MessageException {
- boolean checkIsEmpty = true;
- SOAPHeader s = _getHeader(checkIsEmpty, false); // perchè la struttura del soap header viene mantenuta anche vuota, per preservare i commenti.
- if(s!=null) {
- return this._headerMsgCompleto;
- }
- return null;
- }
- public SOAPHeader getHeader() throws MessageException {
- return _getHeader(false, false);
- }
- public SOAPHeader getModifiableHeader() throws MessageException {
- this.soapHeaderModified = true;
- return _getHeader(false, false);
- }
- public SOAPHeader addHeader() throws MessageException {
- return _getHeader(false, true);
- }
- public boolean isSoapHeaderModified() {
- return this.soapHeaderModified;
- }
- public void setSoapHeaderModified(boolean soapHeaderModified) {
- this.soapHeaderModified = soapHeaderModified;
- }
- private MessageException parseErrorHeader = null;
- private SOAPHeader _getHeader(boolean checkIsEmpty, boolean buildIfEmpty) throws MessageException {
-
- if(this.parseErrorHeader!=null) {
- throw this.parseErrorHeader;
- }
-
- SOAPHeader soapHeader = null;
-
- if(this._headerMsgCompleto!=null) {
- try{
- soapHeader = this._headerMsgCompleto.castAsSoap().getSOAPHeader();
- }catch(Throwable t) {
- throw SoapUtils.buildMessageException("Error during access header: "+t.getMessage(),t);
- }
- }
- else {
- if(this._headerMsgCompleto==null && this.header!=null) {
- try {
- //System.out.println("COSTRUISCO ["+this.header+"]");
- this._headerMsgCompleto = buildOp2Message(this.header.getBytes(), this.getMessageType());
- soapHeader = this._headerMsgCompleto.castAsSoap().getSOAPHeader();
- //System.out.println("COSTRUITO ["+org.openspcoop2.message.xml.XMLUtils.getInstance(this.msgFactory).toString(soapHeader)+"]");
-
- if(soapHeader!=null) {
- if("".equals(this.prefixEnvelope)) {
- this._headerMsgCompleto.castAsSoap().getSOAPPart().getEnvelope().setPrefix("");
- }
- if("".equals(this.prefixHeader)) {
- soapHeader.setPrefix("");
- }
- //System.out.println("HEADER COSTRUITO DA QUANTO LETTO CON SAAJ PREFIX ["+soapHeader.getPrefix()+"], LETTO: "+this.header);
- }
-
- //this._header = XMLUtils.getInstance().newElement(this.header.getBytes());
-
- this.header = null; // libero memoria
-
- }catch(Throwable t) {
- //System.out.println("ECCEZIONE!");
- this.parseErrorHeader = SoapUtils.buildMessageException("Invalid header ("+this.header+"): "+t.getMessage(),t);
- throw this.parseErrorHeader;
- }
- }
-
- if(this._headerMsgCompleto==null && buildIfEmpty) {
- try {
- String xmlns = "";
- if(this.prefixEnvelope!=null && !"".equals(this.prefixEnvelope)) {
- xmlns=":"+this.prefixEnvelope;
- if(xmlns.endsWith(":") && xmlns.length()>1) {
- xmlns = xmlns.substring(0, xmlns.length()-1);
- }
- }
- String envelope = "<"+this.prefixEnvelope+"Envelope xmlns"+xmlns+"=\""+this.namespace+"\"><"+this.prefixEnvelope+"Header/></"+this.prefixEnvelope+"Envelope>";
- this._headerMsgCompleto = buildOp2Message(envelope.getBytes(), this.getMessageType());
- soapHeader = this._headerMsgCompleto.castAsSoap().getSOAPHeader();
- if("".equals(xmlns)) {
- this._headerMsgCompleto.castAsSoap().getSOAPPart().getEnvelope().setPrefix("");
- soapHeader.setPrefix("");
- }
- //System.out.println("HEADER CREATO CON SAAJ PREFIX ["+soapHeader.getPrefix()+"]");
- this.soapHeaderModified = true;
- }catch(Throwable t) {
- throw SoapUtils.buildMessageException("Build header failed: "+t.getMessage(),t);
- }
- }
- }
-
- if(soapHeader!=null && checkIsEmpty) {
- Node n = SoapUtils.getFirstNotEmptyChildNode(OpenSPCoop2MessageFactory.getDefaultMessageFactory(), soapHeader, false);
- if(n==null) {
- soapHeader = null;
- }
- }
-
- /*if(soapHeader!=null) {
- try {
- TransformerConfig xmlConfig = new TransformerConfig();
- xmlConfig.setOmitXMLDeclaration(true);
- xmlConfig.setCharset(this.isCharset);
- System.out.println("COSTRUITO ["+org.openspcoop2.message.xml.XMLUtils.getInstance(OpenSPCoop2MessageFactory.getDefaultMessageFactory()).toString(soapHeader, xmlConfig)+"]");
- org.w3c.dom.NodeList l = soapHeader.getChildNodes();
- for (int i = 0; i < l.getLength(); i++) {
- System.out.println("BEFORE ["+l.item(i).getClass().getName()+"] ["+l.item(i).getLocalName()+"]");
- }
- }catch(Throwable t) {
- System.out.println("ERRORE");
- }
- }*/
-
- return soapHeader;
- }
- public void clearHeader() {
- this._headerMsgCompleto=null;
- this.soapHeaderOptimizable=false;
- }
- // public Element getRootElement() {
- // return this.rootElement;
- // }
- public String getRootElementNamespace() {
- return this.rootElementNamespace;
- }
- public String getRootElementLocalName() {
- return this.rootElementLocalName;
- }
- public String getRootElementPrefix() {
- return this.rootElementPrefix;
- }
-
- private static ThreadLocal<SAXParser> saxParserThreadLocal =
- new ThreadLocal<SAXParser>() {
- @Override
- protected SAXParser initialValue() {
- try{
- SAXParserFactory saxFactory = XMLUtils.getInstance().getSAXParserFactory();
- // try {
- // saxFactory.setFeature("jdk.xml.resetSymbolTable", true);
- // } catch(Throwable e) {
- // }
- saxFactory.setNamespaceAware(true);
- SAXParser parser = saxFactory.newSAXParser();
- return parser;
- }catch(Throwable t){
- throw new RuntimeException("Inizializzazione SAXParser fallita: "+t.getMessage(),t);
- }
- }
- };
- private static SAXParser getParser() {
- return saxParserThreadLocal.get();
- }
- public static void removeParser() {
- saxParserThreadLocal.remove();
- }
-
- private static void returnParser(SAXParser saxParser) {
- saxParser.reset();
- }
-
- private static OpenSPCoop2Message buildOp2Message(byte[] bytes, MessageType messageType) throws Exception {
- MimeHeaders mhs = new MimeHeaders();
- mhs.addHeader(HttpConstants.CONTENT_TYPE, MessageType.SOAP_11.equals(messageType) ? HttpConstants.CONTENT_TYPE_SOAP_1_1 : HttpConstants.CONTENT_TYPE_SOAP_1_2);
- OpenSPCoop2Message msg = null;
- try(ByteArrayInputStream bin = new ByteArrayInputStream(bytes)){
- if(MessageType.SOAP_11.equals(messageType)){
- msg = new OpenSPCoop2Message_saaj_11_impl(OpenSPCoop2MessageFactory.getDefaultMessageFactory(), mhs, bin);
- }
- else {
- msg = new OpenSPCoop2Message_saaj_12_impl(OpenSPCoop2MessageFactory.getDefaultMessageFactory(), mhs, bin);
- }
- }
- return msg;
- }
-
- public boolean isSoapHeaderOptimizable() {
- return SOAP_HEADER_OPTIMIZATION_ENABLED && this.soapHeaderOptimizable;
- }
-
- public void writeOptimizedHeaderTo(InputStream is, OutputStream osParam, boolean consumeHeader) throws Exception {
- if(!this.soapHeaderOptimizable) {
- throw new Exception("SOAPHeader not optimizable");
- }
-
- if(this._headerMsgCompleto==null) {
- throw new Exception("SOAPMessage Optimized undefined");
- }
- SOAPHeader soapHeader = this._headerMsgCompleto.castAsSoap().getSOAPHeader();
- if(soapHeader==null) {
- throw new Exception("SOAPHeader undefined");
- }
-
- TransformerConfig xmlConfig = new TransformerConfig();
- xmlConfig.setOmitXMLDeclaration(true);
- xmlConfig.setCharset(this.isCharset);
-
- long indexBody = this.startBodyOffset;
- if(this.endHeaderOffset>0) {
- indexBody = this.endHeaderOffset+1;
- }
-
- // first
- byte[] buffer = new byte[Utilities.DIMENSIONE_BUFFER];
- int letti = 0;
- long index = 0;
- boolean writeHeader = false;
-
- boolean debug = false;
- OutputStream os = null;
- if(debug) {
- os = new ByteArrayOutputStream();
- }
- else {
- os = osParam;
- }
- while( (letti=is.read(buffer, 0, Utilities.DIMENSIONE_BUFFER)) != -1 ){
-
- if(index<this.startHeaderOffset) {
- for (int i=0; i < letti; i++) {
- if(!writeHeader || index>=indexBody) {
- os.write(buffer[i]);
- }
- index++;
-
- if(index==this.startHeaderOffset) {
- if(debug) {
- os.flush();
- //System.out.println("SCRITTO FINO A HEADER ["+os.toString()+"]");
- }
-
- //os.write(OpenSPCoop2MessageFactory.getAsByte(OpenSPCoop2MessageFactory.getDefaultMessageFactory(), this._header, true));
- os.write(org.openspcoop2.message.xml.MessageXMLUtils.getInstance(OpenSPCoop2MessageFactory.getDefaultMessageFactory()).toByteArray(soapHeader, xmlConfig));
- writeHeader = true;
- if(debug) {
- os.flush();
- //System.out.println("SCRITTO HEADER ["+os.toString()+"]");
- }
- }
- }
- }
- else {
- if(!writeHeader) {
- //os.write(OpenSPCoop2MessageFactory.getAsByte(OpenSPCoop2MessageFactory.getDefaultMessageFactory(), this._header, true));
- os.write(org.openspcoop2.message.xml.MessageXMLUtils.getInstance(OpenSPCoop2MessageFactory.getDefaultMessageFactory()).toByteArray(soapHeader, xmlConfig));
- writeHeader = true;
- if(debug) {
- os.flush();
- //System.out.println("SCRITTO HEADER GIRO SUCCESSIVO ["+os.toString()+"]");
- }
- }
- if(index>=indexBody) {
- os.write(buffer, 0, letti);
- index = index+letti;
- }
- else {
- for (int i=0; i < letti; i++) {
- if(index>=indexBody) {
- os.write(buffer[i]);
- }
- index++;
- }
- }
- if(debug) {
- os.flush();
- //System.out.println("SCRITTO PEZZO ["+os.toString()+"]");
- }
- }
-
- }
-
- if(debug) {
- os.flush();
- //System.out.println("SCRITTO TUTTO ["+os.toString()+"]");
- }
-
-
- // flush
- os.flush();
-
- // ** rilascio memoria **
- if(consumeHeader) {
- this._headerMsgCompleto = null;
- this.soapHeaderOptimizable=false;
- this.bufferedInputStream = null;
- }
- }
- }