001    /*
002     * Licensed to the Apache Software Foundation (ASF) under one or more
003     * contributor license agreements.  See the NOTICE file distributed with
004     * this work for additional information regarding copyright ownership.
005     * The ASF licenses this file to You under the Apache License, Version 2.0
006     * (the "License"); you may not use this file except in compliance with
007     * the License.  You may obtain a copy of the License at
008     *
009     *      http://www.apache.org/licenses/LICENSE-2.0
010     *
011     * Unless required by applicable law or agreed to in writing, software
012     * distributed under the License is distributed on an "AS IS" BASIS,
013     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014     * See the License for the specific language governing permissions and
015     * limitations under the License.
016     */
017    package org.apache.servicemix.common.util;
018    
019    import javax.jbi.JBIException;
020    import javax.jbi.component.ComponentContext;
021    import javax.jbi.messaging.MessageExchange;
022    import javax.jbi.servicedesc.ServiceEndpoint;
023    import javax.xml.namespace.QName;
024    
025    import org.w3c.dom.Document;
026    import org.w3c.dom.DocumentFragment;
027    import org.w3c.dom.Element;
028    import org.w3c.dom.Text;
029    
030    public class URIResolver {
031    
032        /**
033         * The uri to resolve
034         */
035        private String uri;
036    
037        public URIResolver() {
038        }
039    
040        public URIResolver(String uri) {
041            this.uri = uri;
042        }
043    
044        protected JBIException createServiceUnavailableException() {
045            return new JBIException("Unable to resolve uri: " + uri);
046        }
047    
048        public ServiceEndpoint[] resolveAvailableEndpoints(ComponentContext context,
049                                                           MessageExchange exchange) throws JBIException {
050            if (uri.startsWith("interface:")) {
051                String u = this.uri.substring(10);
052                String[] parts = split2(u);
053                return context.getEndpoints(new QName(parts[0], parts[1]));
054            } else if (uri.startsWith("operation:")) {
055                // ignore operation
056                String u = this.uri.substring(10);
057                String[] parts = split3(u);
058                return context.getEndpoints(new QName(parts[0], parts[1]));
059            } else if (uri.startsWith("service:")) {
060                String u = this.uri.substring(8);
061                String[] parts = split2(u);
062                return context.getEndpointsForService(new QName(parts[0], parts[1]));
063            } else if (uri.startsWith("endpoint:")) {
064                String u = this.uri.substring(9);
065                String[] parts = split3(u);
066                ServiceEndpoint se = context.getEndpoint(new QName(parts[0], parts[1]), parts[2]);
067                if (se != null) {
068                    return new ServiceEndpoint[] {se };
069                }
070            // Try an EPR resolution
071            } else {
072                DocumentFragment epr = createWSAEPR(uri);
073                ServiceEndpoint se = context.resolveEndpointReference(epr);
074                if (se != null) {
075                    return new ServiceEndpoint[] {se };
076                }
077            }
078            return null;
079        }
080    
081        /**
082         * @return the uri
083         */
084        public String getUri() {
085            return uri;
086        }
087    
088        /**
089         * @param uri the uri to set
090         */
091        public void setUri(String uri) {
092            this.uri = uri;
093        }
094    
095        public static DocumentFragment createWSAEPR(String uri) {
096            Document doc;
097            try {
098                doc = DOMUtil.newDocument();
099            } catch (Exception e) {
100                throw new RuntimeException(e);
101            }
102            DocumentFragment epr = doc.createDocumentFragment();
103            Element root = doc.createElement("epr");
104            Element address = doc.createElementNS(WSAddressingConstants.WSA_NAMESPACE_200508,
105                                                  WSAddressingConstants.WSA_PREFIX + ":" + WSAddressingConstants.EL_ADDRESS);
106            Text txt = doc.createTextNode(uri);
107            address.appendChild(txt);
108            root.appendChild(address);
109            epr.appendChild(root);
110            return epr;
111        }
112    
113        /**
114         * Configure a JBI exchange with the given URI as the target
115         *
116         * @param exchange the exchange to configure
117         * @param context a component context used to resolve endpoints
118         * @param uri the target uri
119         */
120        public static void configureExchange(MessageExchange exchange, ComponentContext context, String uri) {
121            if (exchange == null) {
122                throw new NullPointerException("exchange is null");
123            }
124            if (context == null) {
125                throw new NullPointerException("context is null");
126            }
127            if (uri == null) {
128                throw new NullPointerException("uri is null");
129            }
130            if (uri.startsWith("interface:")) {
131                String uri2 = uri.substring(10);
132                String[] parts = URIResolver.split2(uri2);
133                exchange.setInterfaceName(new QName(parts[0], parts[1]));
134            } else if (uri.startsWith("operation:")) {
135                String uri2 = uri.substring(10);
136                String[] parts = URIResolver.split3(uri2);
137                exchange.setInterfaceName(new QName(parts[0], parts[1]));
138                exchange.setOperation(new QName(parts[0], parts[2]));
139            } else if (uri.startsWith("service:")) {
140                String uri2 = uri.substring(8);
141                String[] parts = URIResolver.split2(uri2);
142                exchange.setService(new QName(parts[0], parts[1]));
143            } else if (uri.startsWith("endpoint:")) {
144                String uri2 = uri.substring(9);
145                String[] parts = URIResolver.split3(uri2);
146                ServiceEndpoint se = context.getEndpoint(new QName(parts[0], parts[1]), parts[2]);
147                exchange.setEndpoint(se);
148            } else {
149                DocumentFragment epr = URIResolver.createWSAEPR(uri);
150                ServiceEndpoint se = context.resolveEndpointReference(epr);
151                exchange.setEndpoint(se);
152            }
153        }
154    
155        public static String[] split3(String uri) {
156            char sep;
157            uri = uri.trim();
158            if (uri.indexOf('/') > 0) {
159                sep = '/';
160            } else {
161                sep = ':';
162            }
163            int idx1 = uri.lastIndexOf(sep);
164            int idx2 = uri.lastIndexOf(sep, idx1 - 1);
165            if (idx1 < 0 || idx2 < 0) {
166                throw new IllegalArgumentException("Bad syntax: expected [part0][sep][part1][sep][part2]");
167            }
168            String epName = uri.substring(idx1 + 1);
169            String svcName = uri.substring(idx2 + 1, idx1);
170            String nsUri   = uri.substring(0, idx2);
171            return new String[] {nsUri, svcName, epName };
172        }
173    
174        public static String[] split2(String uri) {
175            char sep;
176            uri = uri.trim();
177            if (uri.indexOf('/') > 0) {
178                sep = '/';
179            } else {
180                sep = ':';
181            }
182            int idx1 = uri.lastIndexOf(sep);
183            if (idx1 < 0) {
184                throw new IllegalArgumentException("Bad syntax: expected [part0][sep][part1]");
185            }
186            String svcName = uri.substring(idx1 + 1);
187            String nsUri   = uri.substring(0, idx1);
188            return new String[] {nsUri, svcName };
189        }
190    
191    }