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.camel.component.ahc.helper;
018    
019    import java.io.IOException;
020    import java.io.InputStream;
021    import java.io.ObjectInputStream;
022    import java.io.ObjectOutputStream;
023    import java.io.OutputStream;
024    import java.io.UnsupportedEncodingException;
025    import java.net.URI;
026    import java.net.URISyntaxException;
027    
028    import org.apache.camel.Exchange;
029    import org.apache.camel.RuntimeExchangeException;
030    import org.apache.camel.component.ahc.AhcEndpoint;
031    import org.apache.camel.converter.IOConverter;
032    import org.apache.camel.util.IOHelper;
033    import org.apache.camel.util.URISupport;
034    import org.apache.camel.util.UnsafeUriCharactersEncoder;
035    
036    /**
037     *
038     */
039    public final class AhcHelper {
040    
041        private AhcHelper() {
042            // Helper class
043        }
044    
045        /**
046         * Writes the given object as response body to the output stream
047         *
048         * @param stream output stream
049         * @param target   object to write
050         * @throws java.io.IOException is thrown if error writing
051         */
052        public static void writeObjectToStream(OutputStream stream, Object target) throws IOException {
053            ObjectOutputStream oos = new ObjectOutputStream(stream);
054            oos.writeObject(target);
055            oos.flush();
056            IOHelper.close(oos);
057        }
058    
059        /**
060         * Deserializes the input stream to a Java object
061         *
062         * @param is input stream for the Java object
063         * @return the java object, or <tt>null</tt> if input stream was <tt>null</tt>
064         * @throws ClassNotFoundException is thrown if class not found
065         * @throws IOException can be thrown
066         */
067        public static Object deserializeJavaObjectFromStream(InputStream is) throws ClassNotFoundException, IOException {
068            if (is == null) {
069                return null;
070            }
071    
072            Object answer = null;
073            ObjectInputStream ois = new ObjectInputStream(is);
074            try {
075                answer = ois.readObject();
076            } finally {
077                IOHelper.close(ois);
078            }
079    
080            return answer;
081        }
082    
083        public static void setCharsetFromContentType(String contentType, Exchange exchange) {
084            if (contentType != null) {
085                // find the charset and set it to the Exchange
086                int index = contentType.indexOf("charset=");
087                if (index > 0) {
088                    String charset = contentType.substring(index + 8);
089                    exchange.setProperty(Exchange.CHARSET_NAME, IOConverter.normalizeCharset(charset));
090                }
091            }
092        }
093    
094        /**
095         * Creates the URL to invoke.
096         *
097         * @param exchange the exchange
098         * @param endpoint the endpoint
099         * @return the URL to invoke
100         * @throws java.net.URISyntaxException is thrown if the URL is invalid
101         * @throws UnsupportedEncodingException 
102         */
103        public static String createURL(Exchange exchange, AhcEndpoint endpoint) throws URISyntaxException, UnsupportedEncodingException {
104            String url = doCreateURL(exchange, endpoint);
105            return URISupport.normalizeUri(url);
106        }
107    
108        private static String doCreateURL(Exchange exchange, AhcEndpoint endpoint) {
109            String uri = null;
110            if (!(endpoint.isBridgeEndpoint())) {
111                uri = exchange.getIn().getHeader(Exchange.HTTP_URI, String.class);
112            }
113            if (uri == null) {
114                uri = endpoint.getHttpUri().toASCIIString();
115            }
116    
117            // resolve placeholders in uri
118            try {
119                uri = exchange.getContext().resolvePropertyPlaceholders(uri);
120            } catch (Exception e) {
121                throw new RuntimeExchangeException("Cannot resolve property placeholders with uri: " + uri, exchange, e);
122            }
123    
124            // append HTTP_PATH to HTTP_URI if it is provided in the header
125            String path = exchange.getIn().getHeader(Exchange.HTTP_PATH, String.class);
126            if (path != null) {
127                if (path.startsWith("/")) {
128                    URI baseURI;
129                    String baseURIString = exchange.getIn().getHeader(Exchange.HTTP_BASE_URI, String.class);
130                    try {
131                        if (baseURIString == null) {
132                            if (exchange.getFromEndpoint() != null) {
133                                baseURIString = exchange.getFromEndpoint().getEndpointUri();
134                            } else {
135                                // will set a default one for it
136                                baseURIString = "/";
137                            }
138                        }
139                        baseURI = new URI(baseURIString);
140                        String basePath = baseURI.getPath();
141                        if (path.startsWith(basePath)) {
142                            path = path.substring(basePath.length());
143                            if (path.startsWith("/")) {
144                                path = path.substring(1);
145                            }
146                        } else {
147                            throw new RuntimeExchangeException("Cannot analyze the Exchange.HTTP_PATH header, due to: cannot find the right HTTP_BASE_URI", exchange);
148                        }
149                    } catch (Throwable t) {
150                        throw new RuntimeExchangeException("Cannot analyze the Exchange.HTTP_PATH header, due to: " + t.getMessage(), exchange, t);
151                    }
152                }
153                if (path.length() > 0) {
154                    // make sure that there is exactly one "/" between HTTP_URI and
155                    // HTTP_PATH
156                    if (!uri.endsWith("/")) {
157                        uri = uri + "/";
158                    }
159                    uri = uri.concat(path);
160                }
161            }
162    
163            // ensure uri is encoded to be valid
164            uri = UnsafeUriCharactersEncoder.encode(uri);
165    
166            return uri;
167        }
168    }