1 /* 2 * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package com.sun.xml.internal.ws.api.pipe; 27 28 import com.sun.istack.internal.NotNull; 29 import com.sun.istack.internal.Nullable; 30 import com.sun.xml.internal.ws.api.BindingID; 31 import com.sun.xml.internal.ws.api.pipe.helper.PipeAdapter; 32 import com.sun.xml.internal.ws.api.server.Container; 33 import com.sun.xml.internal.ws.assembler.MetroTubelineAssembler; 34 import com.sun.xml.internal.ws.util.ServiceFinder; 35 import java.util.logging.Level; 36 37 import java.util.logging.Logger; 38 39 /** 40 * Creates {@link TubelineAssembler}. 41 * <p/> 42 * <p/> 43 * To create a tubeline, 44 * the JAX-WS runtime locates {@link TubelineAssemblerFactory}s through 45 * the <tt>META-INF/services/com.sun.xml.internal.ws.api.pipe.TubelineAssemblerFactory</tt> files. 46 * Factories found are checked to see if it supports the given binding ID one by one, 47 * and the first valid {@link TubelineAssembler} returned will be used to create 48 * a tubeline. 49 * 50 * @author Jitendra Kotamraju 51 */ 52 public abstract class TubelineAssemblerFactory { 53 /** 54 * Creates a {@link TubelineAssembler} applicable for the given binding ID. 55 * 56 * @param bindingId The binding ID for which a tubeline will be created, 57 * such as {@link javax.xml.ws.soap.SOAPBinding#SOAP11HTTP_BINDING}. 58 * Must not be null. 59 * @return null if this factory doesn't recognize the given binding ID. 60 */ 61 public abstract TubelineAssembler doCreate(BindingID bindingId); 62 63 /** 64 * @deprecated 65 * Use {@link #create(ClassLoader, BindingID, Container)} 66 */ 67 public static TubelineAssembler create(ClassLoader classLoader, BindingID bindingId) { 68 return create(classLoader,bindingId,null); 69 } 70 71 /** 72 * Locates {@link TubelineAssemblerFactory}s and create 73 * a suitable {@link TubelineAssembler}. 74 * 75 * @param bindingId The binding ID string for which the new {@link TubelineAssembler} 76 * is created. Must not be null. 77 * @param container 78 * if specified, the container is given a chance to specify a {@link TubelineAssembler} 79 * instance. This parameter should be always given on the server, but can be null. 80 * @return Always non-null, since we fall back to our default {@link TubelineAssembler}. 81 */ 82 public static TubelineAssembler create(ClassLoader classLoader, BindingID bindingId, @Nullable Container container) { 83 84 if(container!=null) { 85 // first allow the container to control pipeline for individual endpoint. 86 TubelineAssemblerFactory taf = container.getSPI(TubelineAssemblerFactory.class); 87 if(taf!=null) { 88 TubelineAssembler a = taf.doCreate(bindingId); 89 if (a != null) { 90 return a; 91 } 92 } 93 } 94 95 for (TubelineAssemblerFactory factory : ServiceFinder.find(TubelineAssemblerFactory.class, classLoader)) { 96 TubelineAssembler assembler = factory.doCreate(bindingId); 97 if (assembler != null) { 98 TubelineAssemblerFactory.logger.log(Level.FINE, "{0} successfully created {1}", new Object[]{factory.getClass(), assembler}); 99 return assembler; 100 } 101 } 102 103 // See if there is a PipelineAssembler out there and use it for compatibility. 104 for (PipelineAssemblerFactory factory : ServiceFinder.find(PipelineAssemblerFactory.class,classLoader)) { 105 PipelineAssembler assembler = factory.doCreate(bindingId); 106 if(assembler!=null) { 107 logger.log(Level.FINE, "{0} successfully created {1}", new Object[]{factory.getClass(), assembler}); 108 return new TubelineAssemblerAdapter(assembler); 109 } 110 } 111 112 // default binding IDs that are known 113 return new MetroTubelineAssembler(bindingId, MetroTubelineAssembler.JAXWS_TUBES_CONFIG_NAMES); 114 } 115 116 private static class TubelineAssemblerAdapter implements TubelineAssembler { 117 private PipelineAssembler assembler; 118 119 TubelineAssemblerAdapter(PipelineAssembler assembler) { 120 this.assembler = assembler; 121 } 122 123 @Override 124 public @NotNull Tube createClient(@NotNull ClientTubeAssemblerContext context) { 125 ClientPipeAssemblerContext ctxt = new ClientPipeAssemblerContext( 126 context.getAddress(), context.getWsdlModel(), context.getService(), 127 context.getBinding(), context.getContainer()); 128 return PipeAdapter.adapt(assembler.createClient(ctxt)); 129 } 130 131 @Override 132 public @NotNull Tube createServer(@NotNull ServerTubeAssemblerContext context) { 133 if (!(context instanceof ServerPipeAssemblerContext)) { 134 throw new IllegalArgumentException("{0} is not instance of ServerPipeAssemblerContext"); 135 } 136 return PipeAdapter.adapt(assembler.createServer((ServerPipeAssemblerContext) context)); 137 } 138 } 139 140 private static final Logger logger = Logger.getLogger(TubelineAssemblerFactory.class.getName()); 141 }