/**
 * Copyright 2005 The Apache Software Foundation
 *
 * Licensed 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.nutch.searcher;

import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
import java.util.ArrayList;
import java.util.logging.Logger;

import org.apache.hadoop.io.*;
import org.apache.nutch.html.Entities;
import org.apache.hadoop.util.LogFormatter;

/** Data stored in the index for a hit.
 *
 * <p>Represented as a list of name/value pairs.
 */
public final class HitDetails implements Writable {
  private static final Logger LOG =
    LogFormatter.getLogger("org.apache.nutch.searcher.HitDetails");

  private int length;
  private String[] fields;
  private String[] values;

  public HitDetails() {}

  /** Construct from field names and values arrays. */
  public HitDetails(String[] fields, String[] values) {
    this.length = fields.length;
    this.fields = fields;
    this.values = values;
  }

  /** Construct minimal details from a segment name and document number. */
  public HitDetails(String segment, String url) {
    this(new String[2], new String[2]);
    this.fields[0] = "segment";
    this.values[0] = segment;
    this.fields[1] = "url";
    this.values[1] = url;
  }

  /** Returns the number of fields contained in this. */
  public int getLength() { return length; }

  /** Returns the name of the <code>i</code><sup>th</sup> field. */
  public String getField(int i) { return fields[i]; }

  /** Returns the value of the <code>i</code><sup>th</sup> field. */
  public String getValue(int i) { return values[i]; }
  
  /** Returns the value of the first field with the specified name. */
  public String getValue(String field) {
    for (int i = 0; i < length; i++) {
      if (fields[i].equals(field))
        return values[i];
    }
    return null;
  }

  /** Returns all the values with the specified name. */
  public String[] getValues(String field) {
   ArrayList vals = new ArrayList();
   for (int i=0; i<length; i++) {
     if (fields[i].equals(field)) {
       vals.add(values[i]);
     }
   }
   return (vals.size() > 0)
            ? (String[]) vals.toArray(new String[vals.size()])
            : null;
}

  // javadoc from Writable
  public void write(DataOutput out) throws IOException {
    out.writeInt(length);
    for (int i = 0; i < length; i++) {
      out.writeUTF(fields[i]);
      out.writeUTF(values[i]);
    }
  }
  
  /** Constructs, reads and returns an instance. */
  public static HitDetails read(DataInput in) throws IOException {
    HitDetails result = new HitDetails();
    result.readFields(in);
    return result;
  }

  // javadoc from Writable
  public void readFields(DataInput in) throws IOException {
    length = in.readInt();
    fields = new String[length];
    values = new String[length];
    for (int i = 0; i < length; i++) {
      fields[i] = in.readUTF();
      values[i] = in.readUTF();
    }
  }

  /** Display as a string. */
  public String toString() {
    return getValue("segment") + "/" + getValue("url");
  }

  /** Display as HTML. */
  public String toHtml() {
    String[] vals = null;
    StringBuffer buffer = new StringBuffer();
    buffer.append("<ul>\n");
    for (int i = 0; i < length; i++) {
      buffer.append("<li>");
      buffer.append(fields[i]);
      buffer.append(" = ");
      vals = getValues(fields[i]);
      for (int j=0; j<vals.length; j++) {
        buffer.append(Entities.encode(vals[j]));
        if (j<(vals.length-1)) {
          buffer.append(",");
        }
      }
      buffer.append("</li>\n");
    }
    buffer.append("</ul>\n");
    return buffer.toString();
  }
  


}

@@ -3607,34 +3607,8 @@
 ) %7B%0A
-    String%5B%5D vals = null;%0A
     
@@ -3645,24 +3645,24 @@
 ngBuffer();%0A
+
     buffer.a
@@ -3810,87 +3810,8 @@
 %22);%0A
-      vals = getValues(fields%5Bi%5D);%0A      for (int j=0; j%3Cvals.length; j++) %7B%0A  
     
@@ -3849,97 +3849,18 @@
 (val
+ue
 s%5B
-j
+i
 %5D));%0A
-        if (j%3C(vals.length-1)) %7B%0A          buffer.append(%22,%22);%0A        %7D%0A      %7D%0A
     

Change the way multi-valued fields are displayed in HitDetails