ohair@286: /* ohair@286: * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved. ohair@286: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. ohair@286: * ohair@286: * This code is free software; you can redistribute it and/or modify it ohair@286: * under the terms of the GNU General Public License version 2 only, as ohair@286: * published by the Free Software Foundation. Oracle designates this ohair@286: * particular file as subject to the "Classpath" exception as provided ohair@286: * by Oracle in the LICENSE file that accompanied this code. ohair@286: * ohair@286: * This code is distributed in the hope that it will be useful, but WITHOUT ohair@286: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ohair@286: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License ohair@286: * version 2 for more details (a copy is included in the LICENSE file that ohair@286: * accompanied this code). ohair@286: * ohair@286: * You should have received a copy of the GNU General Public License version ohair@286: * 2 along with this work; if not, write to the Free Software Foundation, ohair@286: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. ohair@286: * ohair@286: * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA ohair@286: * or visit www.oracle.com if you need additional information or have any ohair@286: * questions. ohair@286: */ ohair@286: ohair@286: package com.sun.xml.internal.ws.server; ohair@286: ohair@286: import com.sun.xml.internal.ws.api.SOAPVersion; ohair@286: import com.sun.xml.internal.ws.api.WSBinding; ohair@286: import com.sun.xml.internal.ws.api.message.Message; ohair@286: import com.sun.xml.internal.ws.api.message.Packet; ohair@286: import com.sun.xml.internal.ws.api.model.SEIModel; ohair@286: import com.sun.xml.internal.ws.api.model.wsdl.WSDLPort; ohair@286: import com.sun.xml.internal.ws.api.pipe.NextAction; ohair@286: import com.sun.xml.internal.ws.api.pipe.Tube; ohair@286: import com.sun.xml.internal.ws.api.pipe.TubeCloner; ohair@286: import com.sun.xml.internal.ws.api.pipe.helper.AbstractTubeImpl; ohair@286: import com.sun.xml.internal.ws.api.server.WSEndpoint; ohair@286: import com.sun.xml.internal.ws.fault.SOAPFaultBuilder; ohair@286: import com.sun.xml.internal.ws.util.pipe.AbstractSchemaValidationTube; ohair@286: import org.xml.sax.SAXException; ohair@286: ohair@286: import javax.xml.transform.Source; ohair@286: import javax.xml.validation.Schema; ohair@286: import javax.xml.validation.Validator; ohair@286: import javax.xml.ws.WebServiceException; ohair@286: import java.util.logging.Level; ohair@286: import java.util.logging.Logger; ohair@286: ohair@286: /** ohair@286: * {@link Tube} that does the schema validation on the server side. ohair@286: * ohair@286: * @author Jitendra Kotamraju ohair@286: */ ohair@286: public class ServerSchemaValidationTube extends AbstractSchemaValidationTube { ohair@286: ohair@286: private static final Logger LOGGER = Logger.getLogger(ServerSchemaValidationTube.class.getName()); ohair@286: ohair@286: private final Schema schema; ohair@286: private final Validator validator; ohair@286: ohair@286: private final boolean noValidation; ohair@286: private final SEIModel seiModel; ohair@286: private final WSDLPort wsdlPort; ohair@286: ohair@286: public ServerSchemaValidationTube(WSEndpoint endpoint, WSBinding binding, ohair@286: SEIModel seiModel, WSDLPort wsdlPort, Tube next) { ohair@286: super(binding, next); ohair@286: this.seiModel = seiModel; ohair@286: this.wsdlPort = wsdlPort; ohair@286: ohair@286: if (endpoint.getServiceDefinition() != null) { ohair@286: MetadataResolverImpl mdresolver = new MetadataResolverImpl(endpoint.getServiceDefinition()); ohair@286: Source[] sources = getSchemaSources(endpoint.getServiceDefinition(), mdresolver); ohair@286: for(Source source : sources) { ohair@286: LOGGER.fine("Constructing service validation schema from = "+source.getSystemId()); ohair@286: //printDOM((DOMSource)source); ohair@286: } ohair@286: if (sources.length != 0) { ohair@286: noValidation = false; ohair@286: sf.setResourceResolver(mdresolver); ohair@286: try { ohair@286: schema = sf.newSchema(sources); ohair@286: } catch(SAXException e) { ohair@286: throw new WebServiceException(e); ohair@286: } ohair@286: validator = schema.newValidator(); ohair@286: return; ohair@286: } ohair@286: } ohair@286: noValidation = true; ohair@286: schema = null; ohair@286: validator = null; ohair@286: } ohair@286: ohair@286: protected Validator getValidator() { ohair@286: return validator; ohair@286: } ohair@286: ohair@286: protected boolean isNoValidation() { ohair@286: return noValidation; ohair@286: } ohair@286: ohair@286: @Override ohair@286: public NextAction processRequest(Packet request) { ohair@286: if (isNoValidation() || !feature.isInbound() || !request.getMessage().hasPayload() || request.getMessage().isFault()) { ohair@286: return super.processRequest(request); ohair@286: } ohair@286: try { ohair@286: doProcess(request); ohair@286: } catch(SAXException se) { ohair@286: LOGGER.log(Level.WARNING, "Client Request doesn't pass Service's Schema Validation", se); ohair@286: // Client request is invalid. So sending specific fault code ohair@286: // Also converting this to fault message so that handlers may get ohair@286: // to see the message. ohair@286: SOAPVersion soapVersion = binding.getSOAPVersion(); ohair@286: Message faultMsg = SOAPFaultBuilder.createSOAPFaultMessage( ohair@286: soapVersion, null, se, soapVersion.faultCodeClient); ohair@286: return doReturnWith(request.createServerResponse(faultMsg, ohair@286: wsdlPort, seiModel, binding)); ohair@286: } ohair@286: return super.processRequest(request); ohair@286: } ohair@286: ohair@286: @Override ohair@286: public NextAction processResponse(Packet response) { ohair@286: if (isNoValidation() || !feature.isOutbound() || response.getMessage() == null || !response.getMessage().hasPayload() || response.getMessage().isFault()) { ohair@286: return super.processResponse(response); ohair@286: } ohair@286: try { ohair@286: doProcess(response); ohair@286: } catch(SAXException se) { ohair@286: // TODO: Should we convert this to fault Message ?? ohair@286: throw new WebServiceException(se); ohair@286: } ohair@286: return super.processResponse(response); ohair@286: } ohair@286: ohair@286: protected ServerSchemaValidationTube(ServerSchemaValidationTube that, TubeCloner cloner) { ohair@286: super(that,cloner); ohair@286: //this.docs = that.docs; ohair@286: this.schema = that.schema; // Schema is thread-safe ohair@286: this.validator = schema.newValidator(); ohair@286: this.noValidation = that.noValidation; ohair@286: this.seiModel = that.seiModel; ohair@286: this.wsdlPort = that.wsdlPort; ohair@286: } ohair@286: ohair@286: public AbstractTubeImpl copy(TubeCloner cloner) { ohair@286: return new ServerSchemaValidationTube(this,cloner); ohair@286: } ohair@286: ohair@286: }