org.glassfish.webservices.WsCompile Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of payara-micro Show documentation
Show all versions of payara-micro Show documentation
Micro Distribution of the Payara Project
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 1997-2011 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
* or packager/legal/LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at packager/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
package org.glassfish.webservices;
import java.util.Map;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import javax.xml.namespace.QName;
//JAX-RPC SPI
import com.sun.xml.rpc.spi.JaxRpcObjectFactory;
import com.sun.xml.rpc.spi.tools.CompileTool;
import com.sun.xml.rpc.spi.tools.CompileToolDelegate;
import com.sun.xml.rpc.spi.tools.HandlerChainInfo;
import com.sun.xml.rpc.spi.tools.HandlerInfo;
import com.sun.xml.rpc.spi.tools.Configuration;
import com.sun.xml.rpc.spi.tools.ModelInfo;
import com.sun.xml.rpc.spi.model.Model;
import com.sun.xml.rpc.spi.model.Service;
import com.sun.xml.rpc.spi.model.Port;
import com.sun.xml.rpc.spi.model.ModelProperties;
import com.sun.enterprise.deployment.WebService;
import com.sun.enterprise.deployment.WebServiceEndpoint;
import com.sun.enterprise.deployment.ServiceReferenceDescriptor;
import com.sun.enterprise.deployment.WebServiceHandler;
import com.sun.enterprise.deployment.NameValuePairDescriptor;
/**
* This implementation of WsCompile should be used only internally
* at deployment time (or j2eec). Not meant to be overridden.
*
* @author Kenneth Saks
*/
public final class WsCompile extends CompileToolDelegate {
private Collection generatedFiles;
private WebService webService;
private ServiceReferenceDescriptor serviceRef;
private WsUtil wsUtil = new WsUtil();
private CompileTool wscompile;
private JaxRpcObjectFactory rpcFactory;
// if set, used to override standard configuration
private ModelInfo modelInfo;
// true if wscompile encountered an error.
private boolean error = false;
public WsCompile(CompileTool compileTool, WebService webServiceDesc) {
wscompile = compileTool;
webService = webServiceDesc;
rpcFactory = JaxRpcObjectFactory.newInstance();
}
public WsCompile(CompileTool compileTool,
ServiceReferenceDescriptor serviceRefDesc) {
wscompile = compileTool;
serviceRef = serviceRefDesc;
rpcFactory = JaxRpcObjectFactory.newInstance();
}
public void setModelInfo(ModelInfo info) {
modelInfo = info;
}
public CompileTool getCompileTool() {
return wscompile;
}
/**
* com.sun.xml.rpc.spi.tools.wscompile.CompileToolDelegate overrides.
*/
public Configuration createConfiguration() {
Configuration configuration = null;
if( modelInfo != null ) {
configuration =
rpcFactory.createConfiguration(wscompile.getEnvironment());
configuration.setModelInfo(modelInfo);
}
//else, leave it to the jaxrpc implementation to
//create Configuration
return configuration;
}
public void preOnError() {
error = true;
}
public void postRegisterProcessorActions() {
if( !error) {
if (webService != null) {
setupServiceHandlerChain();
}
// NOTE : Client handler chains are configured at runtime.
}
}
public void postRun() {
generatedFiles = new HashSet();
if( !error ) {
for(Iterator iter = wscompile.getEnvironment().getGeneratedFiles();
iter.hasNext(); ) {
generatedFiles.add( iter.next() );
}
if( webService != null ) {
doServicePostProcessing();
} else if( serviceRef != null ) {
doClientPostProcessing();
}
}
}
//
// WsCompile methods.
//
public Collection getGeneratedFiles() {
return generatedFiles;
}
private void setupServiceHandlerChain() {
Model model = wscompile.getProcessor().getModel();
Collection endpoints = webService.getEndpoints();
for(Iterator eIter = endpoints.iterator(); eIter.hasNext();) {
WebServiceEndpoint nextEndpoint = (WebServiceEndpoint) eIter.next();
if( !nextEndpoint.hasHandlers() ) {
continue;
}
Port port = wsUtil.getPortFromModel(model,
nextEndpoint.getWsdlPort());
if( port == null ) {
throw new IllegalStateException("Model port for endpoint " +
nextEndpoint.getEndpointName() +
" not found");
}
List handlerChain = nextEndpoint.getHandlers();
HandlerChainInfo modelHandlerChain =
port.getServerHCI();
List handlerInfoList = new ArrayList();
// Insert an container handler as the first element.
// This is needed to perform method authorization checks.
HandlerInfo preHandler = rpcFactory.createHandlerInfo();
String handlerClassName = nextEndpoint.implementedByEjbComponent() ?
"org.glassfish.webservices.EjbContainerPreHandler" :
"org.glassfish.webservices.ServletPreHandler";
preHandler.setHandlerClassName(handlerClassName);
handlerInfoList.add(preHandler);
// Collect all roles defined on each handler and set them on
// handler chain. NOTE : There is a bit of a mismatch here between
// 109 and JAXRPC. JAXRPC only defines roles at the handler chain
// level, whereas 109 descriptors put roles at the handler level.
Collection soapRoles = new HashSet();
for(Iterator hIter = handlerChain.iterator(); hIter.hasNext();) {
WebServiceHandler nextHandler =
(WebServiceHandler) hIter.next();
HandlerInfo handlerInfo = createHandlerInfo(nextHandler);
handlerInfoList.add(handlerInfo);
soapRoles.addAll(nextHandler.getSoapRoles());
}
// Insert a container handler as the last element in the chain.
HandlerInfo postHandler = rpcFactory.createHandlerInfo();
handlerClassName = nextEndpoint.implementedByEjbComponent() ?
"org.glassfish.webservices.EjbContainerPostHandler" :
"org.glassfish.webservices.ServletPostHandler";
postHandler.setHandlerClassName(handlerClassName);
handlerInfoList.add(postHandler);
// @@@ should probably use addHandler api instead once
// == bug is fixed.
modelHandlerChain.setHandlersList(handlerInfoList);
for(Iterator roleIter = soapRoles.iterator(); roleIter.hasNext();) {
modelHandlerChain.addRole((String) roleIter.next());
}
}
}
private HandlerInfo createHandlerInfo(WebServiceHandler handler) {
HandlerInfo handlerInfo = rpcFactory.createHandlerInfo();
handlerInfo.setHandlerClassName(handler.getHandlerClass());
for(Iterator iter = handler.getSoapHeaders().iterator();
iter.hasNext();) {
QName next = (QName) iter.next();
handlerInfo.addHeaderName(next);
}
Map properties = handlerInfo.getProperties();
for(Iterator iter = handler.getInitParams().iterator();
iter.hasNext();) {
NameValuePairDescriptor next = (NameValuePairDescriptor)
iter.next();
properties.put(next.getName(), next.getValue());
}
return handlerInfo;
}
private void doServicePostProcessing() {
Model model = wscompile.getProcessor().getModel();
Collection endpoints = webService.getEndpoints();
for(Iterator iter = endpoints.iterator(); iter.hasNext(); ) {
WebServiceEndpoint next = (WebServiceEndpoint) iter.next();
Service service = wsUtil.getServiceForPort(model,
next.getWsdlPort());
if( service == null ) {
service = (Service) model.getServices().next();
System.out.println("Warning : Can't find Service for Endpoint '"
+ next.getEndpointName() + "' Port '" +
next.getWsdlPort() + "'");
System.out.println("Defaulting to "+ service.getName());
}
QName serviceName = service.getName();
next.setServiceNamespaceUri(serviceName.getNamespaceURI());
next.setServiceLocalPart(serviceName.getLocalPart());
Port port = wsUtil.getPortFromModel(model, next.getWsdlPort());
if( port == null ) {
String msg = "Can't find model port for endpoint "
+ next.getEndpointName() + " with wsdl-port " +
next.getWsdlPort();
throw new IllegalStateException(msg);
}
// If port has a tie class name property, use it. Otherwise,
// use naming convention to derive tie class name. If there
// are multiple ports per SEI(binding), then the property then
// the TIE_CLASS_NAME property will be available. In that case,
// a separate tie and stub are generated per port.
String tieClassName = (String)
port.getProperty(ModelProperties.PROPERTY_TIE_CLASS_NAME);
if( tieClassName == null ) {
tieClassName = next.getServiceEndpointInterface() + "_Tie";
}
next.setTieClassName(tieClassName);
if( next.implementedByWebComponent() ) {
wsUtil.updateServletEndpointRuntime(next);
} else {
wsUtil.validateEjbEndpoint(next);
}
String endpointAddressUri = next.getEndpointAddressUri();
if( endpointAddressUri == null ) {
String msg = "Endpoint address uri must be set for endpoint " +
next.getEndpointName();
throw new IllegalStateException(msg);
} else if( endpointAddressUri.indexOf("*") >= 0 ) {
String msg = "Endpoint address uri " + endpointAddressUri +
" for endpoint " + next.getEndpointName() +
" is invalid. It must not contain the '*' character";
throw new IllegalStateException(msg);
} else if( endpointAddressUri.endsWith("/") ) {
String msg = "Endpoint address uri " + endpointAddressUri +
" for endpoint " + next.getEndpointName() +
" is invalid. It must not end with '/'";
throw new IllegalStateException(msg);
}
}
}
private void doClientPostProcessing() {
Model model = wscompile.getProcessor().getModel();
Iterator serviceIter = model.getServices();
Service service = null;
if( serviceRef.hasServiceName() ) {
while( serviceIter.hasNext() ) {
Service next = (Service) serviceIter.next();
if( next.getName().equals(serviceRef.getServiceName()) ) {
service = next;
break;
}
}
if( service == null ) {
throw new IllegalStateException
("Service " + serviceRef.getServiceName() +
" for service-ref " + serviceRef.getName() + " not found");
}
} else {
if( serviceIter.hasNext() ) {
service = (Service) serviceIter.next();
if( serviceIter.hasNext() ) {
throw new IllegalStateException
("service ref " + serviceRef.getName() + " must specify"
+ " service name since its wsdl declares multiple"
+ " services");
}
QName sName = service.getName();
serviceRef.setServiceNamespaceUri(sName.getNamespaceURI());
serviceRef.setServiceLocalPart(sName.getLocalPart());
} else {
throw new IllegalStateException
("service ref " + serviceRef.getName() + " WSDL must " +
"define at least one Service");
}
}
// Use naming convention to derive Generated Service
// implementation class name.
String serviceImpl = service.getJavaIntf().getName() + "_Impl";
serviceRef.setServiceImplClassName(serviceImpl);
}
}