| /* |
| * Licensed to the Apache Software Foundation (ASF) under one or more |
| * contributor license agreements. See the NOTICE file distributed with |
| * this work for additional information regarding copyright ownership. |
| * The ASF licenses this file to You under the Apache License, Version 2.0 |
| * (the "License"); you may not use this file except in compliance with |
| * the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| |
| package org.apache.oodt.xmlquery; |
| |
| import java.util.List; |
| import java.util.StringTokenizer; |
| import org.apache.oodt.product.Retriever; |
| import java.io.InputStream; |
| import java.io.IOException; |
| |
| // FIXME: change MIME type application/vnd.jpl.large-product? |
| |
| /** |
| * A <em>large</em> result is a result for <em>large</em> products. |
| * |
| * What is large? Some might say large is something that exceeds most other things of |
| * like kind in bulk, capacity, quantity, superficial dimensions, or number of constituent |
| * units. Large might be big, great, capacious, extensive. Large might be opposed to |
| * small; as, a large horse; a large house or room; a large lake or pool; a large jug or |
| * spoon; a large vineyard; a large army; a large city. Some might say that particularly |
| * if they're named Webster. |
| * |
| * @author Kelly |
| * @version $Revision: 1.2 $ |
| */ |
| public class LargeResult extends Result { |
| /** |
| * Creates a new <code>LargeResult</code> instance. |
| * |
| * @param result a <code>Result</code> value. |
| */ |
| public LargeResult(Result result) { |
| super(result.getID(), "application/vnd.jpl.large-product", result.getProfileID(), result.getResourceID(), |
| result.getHeaders(), transformMimeType(result)); |
| StringTokenizer st = new StringTokenizer((String) value); |
| st.nextToken(); |
| this.size = Long.parseLong(st.nextToken()); |
| } |
| |
| /** |
| * Creates a new <code>LargeResult</code> instance. |
| * |
| * @param id Result ID. |
| * @param mimeType MIME type. |
| * @param profileID Profile ID. |
| * @param resourceID Resource ID. |
| * @param headers Headers. |
| * @param size Size of the product. |
| */ |
| public LargeResult(String id, String mimeType, String profileID, String resourceID, List headers, long size) { |
| super(id, "application/vnd.jpl.large-product", profileID, resourceID, headers, mimeType + " " + size); |
| this.size = size; |
| } |
| |
| /** |
| * Get the size of the product. |
| * |
| * @return Its size. |
| */ |
| public final long getSize() { |
| return size; |
| } |
| |
| public final String getMimeType() { |
| return new StringTokenizer((String) value).nextToken(); |
| } |
| |
| /** |
| * Return the result's value. |
| * |
| * @return a String. |
| * @deprecated This method always treats its value as if it were a String. Worse, |
| * for very large results, it cannot contain the entire result in memory. Use |
| * {@link #getInputStream} instead to perform stream processing on result data. |
| */ |
| public final Object getValue() { |
| Object value = null; |
| InputStream in = null; |
| try { |
| if (size > Integer.MAX_VALUE) |
| throw new IllegalStateException("Cannot use getValue() for this product, result is too large; " |
| + "use LargeResult.getInputStream instead"); |
| int sizeToRead = (int) size; |
| byte[] buf = new byte[sizeToRead]; |
| int index = 0; |
| int num; |
| in = getInputStream(); |
| while ((num = in.read(buf, index, sizeToRead)) != -1) { |
| index += num; |
| sizeToRead -= num; |
| if (sizeToRead == 0) break; |
| } |
| |
| // OK, this sucks. Sucks sucks sucks. Look, getValue is not to |
| // be used anyway. It sucks. But dammit, there's some annoying |
| // code over in EDRN which is using it when they should be using |
| // getInputStream. Basically, if you call this, you're a hoser. |
| // And if you call it and you're not expecting a String, you're a |
| // loser/hoser. DEPRECATED! |
| value = new String(buf); |
| |
| } catch (IOException ex) { |
| throw new IllegalStateException("Unexpected IOException: " + ex.getMessage()); |
| } finally { |
| if (in != null) try { |
| in.close(); |
| } catch (IOException ignore) {} |
| } |
| return value; |
| } |
| |
| /** Size of the product. */ |
| private long size; |
| |
| /** |
| * Get an input stream that streams the result from the product server. |
| * |
| * @return an <code>InputStream</code> value. |
| * @throws IOException if an error occurs. |
| */ |
| public InputStream getInputStream() throws IOException { |
| return new ChunkedProductInputStream(id, retriever, size); |
| } |
| |
| /** |
| * Given an existing <code>Result</code> yield its MIME type. |
| * |
| * The existing <code>Result</code> might be a <code>LargeResult</code>, in which |
| * case the real MIME type is hidden in the value. Otherwise, it's directly in |
| * the object. |
| * |
| * @param result a <code>Result</code> value. |
| * @return The MIME type. |
| */ |
| private static String transformMimeType(Result result) { |
| if ("application/vnd.jpl.large-product".equals(result.mimeType)) |
| return (String) result.value; |
| else |
| return result.mimeType + " 0"; |
| } |
| |
| /** Serial version unique ID. */ |
| static final long serialVersionUID = -969838775595705444L; |
| } |