[mb-commits] r13631 - in search_server/trunk/servlet/src: main/java/org/musicbrainz/search/servlet test/java/org/musicbrainz/search/servlet

[email protected] Wed, 27 Feb 2013 07:30:09 +0000
Newsgroups gmane.comp.audio.musicbrainz.cvs
Message-ID <E1UAbSr-0006eY-Pu@wiley>
Author: ijabz
Date: 2013-02-27 07:30:09 +0000 (Wed, 27 Feb 2013)
New Revision: 13631

Added:
   search_server/trunk/servlet/src/main/java/org/musicbrainz/search/servlet/EscapingXMLStreamWriter.java
   search_server/trunk/servlet/src/test/java/org/musicbrainz/search/servlet/IssueSearch240Test.java
Modified:
   search_server/trunk/servlet/src/main/java/org/musicbrainz/search/servlet/SearchServerServlet.java
   search_server/trunk/servlet/src/test/java/org/musicbrainz/search/servlet/FindAnnotationTest.java
Log:
#SEARCH-240:Invalid Xml Served:Work In progress

Modified: search_server/trunk/servlet/src/main/java/org/musicbrainz/search/servlet/SearchServerServlet.java
===================================================================
--- search_server/trunk/servlet/src/main/java/org/musicbrainz/search/servlet/SearchServerServlet.java	2013-02-27 06:17:07 UTC (rev 13630)
+++ search_server/trunk/servlet/src/main/java/org/musicbrainz/search/servlet/SearchServerServlet.java	2013-02-27 07:30:09 UTC (rev 13631)
@@ -60,574 +60,671 @@
 import org.musicbrainz.search.servlet.mmd2.AllWriter;
 import org.musicbrainz.search.servlet.mmd2.ResultsWriter;
 
-public class SearchServerServlet extends HttpServlet {
+public class SearchServerServlet extends HttpServlet
+{
 
-  final Logger log = Logger.getLogger(SearchServerServlet.class.getName());
+    final Logger log = Logger.getLogger(SearchServerServlet.class.getName());
 
-  final static int DEFAULT_OFFSET = 0;
-  final static int DEFAULT_MATCHES_LIMIT = 25;
-  final static int MAX_MATCHES_LIMIT = 100;
+    final static int DEFAULT_OFFSET = 0;
+    final static int DEFAULT_MATCHES_LIMIT = 25;
+    final static int MAX_MATCHES_LIMIT = 100;
 
-  public final static String RESPONSE_XML = "xml";
-  public final static String RESPONSE_JSON = "json";
-  public final static String RESPONSE_JSON_NEW = "jsonnew";
+    public final static String RESPONSE_XML = "xml";
+    public final static String RESPONSE_JSON = "json";
+    public final static String RESPONSE_JSON_NEW = "jsonnew";
 
-  final static String WS_VERSION_1 = "1";
-  final static String WS_VERSION_2 = "2";
+    final static String WS_VERSION_1 = "1";
+    final static String WS_VERSION_2 = "2";
 
-  final static String CHARSET = "UTF-8";
+    final static String CHARSET = "UTF-8";
 
-  final static String TYPE_ALL = "all";
-  final static String TYPE_TRACK = "track";
+    final static String TYPE_ALL = "all";
+    final static String TYPE_TRACK = "track";
 
-  private boolean isServletInitialized = false;
+    private boolean isServletInitialized = false;
 
-  // Enabled as long indexes for all resources are available
-  private boolean isSearchAllEnabled = true;
+    // Enabled as long indexes for all resources are available
+    private boolean isSearchAllEnabled = true;
 
-  // When doing search over multiple indexes use this executorservice to run in parallel
-  private final ExecutorService es = Executors.newCachedThreadPool();
+    // When doing search over multiple indexes use this executorservice to run in parallel
+    private final ExecutorService es = Executors.newCachedThreadPool();
 
-  private final EnumMap<ResourceType, SearchServer> searchers = new EnumMap<ResourceType, SearchServer>(
-      ResourceType.class);
-  private final EnumMap<ResourceType, SearchServer> dismaxSearchers = new EnumMap<ResourceType, SearchServer>(
-      ResourceType.class);
+    private final EnumMap<ResourceType, SearchServer> searchers = new EnumMap<ResourceType, SearchServer>(
+            ResourceType.class);
+    private final EnumMap<ResourceType, SearchServer> dismaxSearchers = new EnumMap<ResourceType, SearchServer>(
+            ResourceType.class);
 
-  private final String initMessage = null;
-  private static String searchWebPage = "";
-  private static boolean isRateLimiterEnabled = false;
-  private static boolean isAdminRemoteEnabled = false;
+    private final String initMessage = null;
+    private static String searchWebPage = "";
+    private static boolean isRateLimiterEnabled = false;
+    private static boolean isAdminRemoteEnabled = false;
 
-  @Override
-  public void init() {
-    init(true);
-  }
+    @Override
+    public void init()
+    {
+        init(true);
+    }
 
-  /**
-   * If you have indexes that are available this reads from the new indexes and closes the existing readers
-   * 
-   * @param useMMapDirectory
-   */
-  public void init(boolean useMMapDirectory) {
+    /**
+     * If you have indexes that are available this reads from the new indexes and closes the existing readers
+     *
+     * @param useMMapDirectory
+     */
+    public void init(boolean useMMapDirectory)
+    {
 
-    searchWebPage = getServletConfig().getInitParameter("search_webpage");
+        searchWebPage = getServletConfig().getInitParameter("search_webpage");
 
-    String isAdminRemote = getServletConfig().getInitParameter("remoteadmin_enabled");
-    isAdminRemoteEnabled = Boolean.parseBoolean(isAdminRemote);
+        String isAdminRemote = getServletConfig().getInitParameter("remoteadmin_enabled");
+        isAdminRemoteEnabled = Boolean.parseBoolean(isAdminRemote);
 
-    String rateLimiterEnabled = getServletConfig().getInitParameter("ratelimitserver_enabled");
-    initRateLimiter(rateLimiterEnabled);
+        String rateLimiterEnabled = getServletConfig().getInitParameter("ratelimitserver_enabled");
+        initRateLimiter(rateLimiterEnabled);
 
-    String indexDir = getServletConfig().getInitParameter("index_dir");
-    if (useMMapDirectory) {
-      log.info("Start:Loading Indexes from " + indexDir + ",Type:mmap," + "MaxHeap:"
-          + ManagementFactory.getMemoryMXBean().getHeapMemoryUsage().getMax());
-    } else {
-      log.info("Start:loading Indexes from " + indexDir + ",Type:nfio," + "MaxHeap:"
-          + ManagementFactory.getMemoryMXBean().getHeapMemoryUsage().getMax());
-    }
+        String indexDir = getServletConfig().getInitParameter("index_dir");
+        if (useMMapDirectory)
+        {
+            log.info("Start:Loading Indexes from " + indexDir + ",Type:mmap," + "MaxHeap:"
+                    + ManagementFactory.getMemoryMXBean().getHeapMemoryUsage().getMax());
+        } else
+        {
+            log.info("Start:loading Indexes from " + indexDir + ",Type:nfio," + "MaxHeap:"
+                    + ManagementFactory.getMemoryMXBean().getHeapMemoryUsage().getMax());
+        }
 
-    // Initialize all search servers
-    for (ResourceType resourceType : ResourceType.values()) {
+        // Initialize all search servers
+        for (ResourceType resourceType : ResourceType.values())
+        {
 
-      File indexFileDir = new File(indexDir + System.getProperty("file.separator") + resourceType.getIndexName()
-          + "_index");
+            File indexFileDir = new File(indexDir + System.getProperty("file.separator") + resourceType.getIndexName()
+                    + "_index");
 
-      AbstractSearchServer searchServer = null;
-      AbstractDismaxSearchServer dismaxSearchServer = null;
+            AbstractSearchServer searchServer = null;
+            AbstractDismaxSearchServer dismaxSearchServer = null;
 
-      try {
-        Directory directory = useMMapDirectory ? new MMapDirectory(indexFileDir) : new NIOFSDirectory(indexFileDir);
-        SearcherManager searcherManager = new SearcherManager(directory, new MusicBrainzSearcherFactory(resourceType));
-        searchServer = resourceType.getSearchServerClass().getConstructor(SearcherManager.class).newInstance(searcherManager);
-        dismaxSearchServer = resourceType.getDismaxSearchServerClass().getConstructor(AbstractSearchServer.class)
-            .newInstance(searchServer);
+            try
+            {
+                Directory directory = useMMapDirectory ? new MMapDirectory(indexFileDir) : new NIOFSDirectory(indexFileDir);
+                SearcherManager searcherManager = new SearcherManager(directory, new MusicBrainzSearcherFactory(resourceType));
+                searchServer = resourceType.getSearchServerClass().getConstructor(SearcherManager.class).newInstance(searcherManager);
+                dismaxSearchServer = resourceType.getDismaxSearchServerClass().getConstructor(AbstractSearchServer.class)
+                        .newInstance(searchServer);
 
-      } catch (CorruptIndexException e) {
-        log.warning("Could not load " + resourceType.getIndexName() + " index, index is corrupted: " + e.getMessage());
-        if (resourceType.isUsedBySearchAll()) {
-          isSearchAllEnabled = false;
-        }
-      } catch (IOException e) {
-        log.warning("Could not load " + resourceType.getIndexName() + " index: " + e.getMessage());
-        if (resourceType.isUsedBySearchAll()) {
-          isSearchAllEnabled = false;
-        }
-      } catch (Exception e) {
-        log.log(Level.WARNING, "Could not load " + resourceType.getIndexName() + " index: " + e.getMessage(), e);
-        if (resourceType.isUsedBySearchAll()) {
-          isSearchAllEnabled = false;
-        }
-      }
+            }
+            catch (CorruptIndexException e)
+            {
+                log.warning("Could not load " + resourceType.getIndexName() + " index, index is corrupted: " + e.getMessage());
+                if (resourceType.isUsedBySearchAll())
+                {
+                    isSearchAllEnabled = false;
+                }
+            }
+            catch (IOException e)
+            {
+                log.warning("Could not load " + resourceType.getIndexName() + " index: " + e.getMessage());
+                if (resourceType.isUsedBySearchAll())
+                {
+                    isSearchAllEnabled = false;
+                }
+            }
+            catch (Exception e)
+            {
+                log.log(Level.WARNING, "Could not load " + resourceType.getIndexName() + " index: " + e.getMessage(), e);
+                if (resourceType.isUsedBySearchAll())
+                {
+                    isSearchAllEnabled = false;
+                }
+            }
 
-      // Close old search server, incRef/decRef counting will ensure not closed until no longer in use.
-      SearchServer oldSearchServer = searchers.get(resourceType);
-      if (oldSearchServer != null) {
-        try {
-          oldSearchServer.close();
-        } catch (IOException e) {
-          log.severe("Caught exception during closing of index searcher within Init: " + resourceType.getIndexName()
-              + ":" + e.getMessage());
+            // Close old search server, incRef/decRef counting will ensure not closed until no longer in use.
+            SearchServer oldSearchServer = searchers.get(resourceType);
+            if (oldSearchServer != null)
+            {
+                try
+                {
+                    oldSearchServer.close();
+                }
+                catch (IOException e)
+                {
+                    log.severe("Caught exception during closing of index searcher within Init: " + resourceType.getIndexName()
+                            + ":" + e.getMessage());
+                }
+            }
+
+            // Add in new search server and set last updated date
+            searchers.put(resourceType, searchServer);
+            dismaxSearchers.put(resourceType, dismaxSearchServer);
+
         }
-      }
+        log.info("End:loaded Indexes from " + indexDir + ",Type:nfio," + "MaxHeap:"
+                + ManagementFactory.getMemoryMXBean().getHeapMemoryUsage().getMax());
+        isServletInitialized = true;
 
-      // Add in new search server and set last updated date
-      searchers.put(resourceType, searchServer);
-      dismaxSearchers.put(resourceType, dismaxSearchServer);
-
     }
-    log.info("End:loaded Indexes from " + indexDir + ",Type:nfio," + "MaxHeap:"
-        + ManagementFactory.getMemoryMXBean().getHeapMemoryUsage().getMax());
-    isServletInitialized = true;
 
-  }
+    @Override
+    public void destroy()
+    {
 
-  @Override
-  public void destroy() {
+        log.info("Start:Destroy Indexes");
 
-    log.info("Start:Destroy Indexes");
+        // Close all search servers
+        for (SearchServer searchServer : searchers.values())
+        {
+            if (searchServer == null)
+                continue;
+            try
+            {
+                searchServer.close();
+            }
+            catch (IOException e)
+            {
+                log.severe("Caught exception during closing of index searcher: " + e.getMessage());
+            }
+        }
+        searchers.clear();
+        // Close all dismax search servers
+        for (SearchServer searchServer : dismaxSearchers.values())
+        {
+            if (searchServer == null)
+                continue;
+            try
+            {
+                searchServer.close();
+            }
+            catch (IOException e)
+            {
+                log.severe("Caught exception during closing of index searcher: " + e.getMessage());
+            }
+        }
+        dismaxSearchers.clear();
+        log.info("End:Destroy Indexes");
 
-    // Close all search servers
-    for (SearchServer searchServer : searchers.values()) {
-      if (searchServer == null)
-        continue;
-      try {
-        searchServer.close();
-      } catch (IOException e) {
-        log.severe("Caught exception during closing of index searcher: " + e.getMessage());
-      }
     }
-    searchers.clear();
-    // Close all dismax search servers
-    for (SearchServer searchServer : dismaxSearchers.values()) {
-      if (searchServer == null)
-        continue;
-      try {
-        searchServer.close();
-      } catch (IOException e) {
-        log.severe("Caught exception during closing of index searcher: " + e.getMessage());
-      }
+
+    /**
+     * Init Rate Limiter
+     */
+    private void initRateLimiter(String rateLimiterEnabled)
+    {
+        String rateLimiterHost = getServletConfig().getInitParameter("ratelimitserver_host");
+        String rateLimiterPort = getServletConfig().getInitParameter("ratelimitserver_port");
+        log.info("RateLimiter:" + rateLimiterEnabled + ":RateLimiterHost:" + rateLimiterHost + ":Port:" + rateLimiterPort);
+        isRateLimiterEnabled = Boolean.parseBoolean(rateLimiterEnabled);
+        if (isRateLimiterEnabled)
+        {
+            RateLimiterChecker.init(rateLimiterHost, rateLimiterPort);
+        }
     }
-    dismaxSearchers.clear();
-    log.info("End:Destroy Indexes");
 
-  }
+    /**
+     * If Index has just been updated (Documents added or removed from existing index) you can use this method to read the
+     * latest documents from the index.
+     */
+    protected void reloadIndexes()
+    {
 
-  /**
-   * Init Rate Limiter
-   */
-  private void initRateLimiter(String rateLimiterEnabled) {
-    String rateLimiterHost = getServletConfig().getInitParameter("ratelimitserver_host");
-    String rateLimiterPort = getServletConfig().getInitParameter("ratelimitserver_port");
-    log.info("RateLimiter:" + rateLimiterEnabled + ":RateLimiterHost:" + rateLimiterHost + ":Port:" + rateLimiterPort);
-    isRateLimiterEnabled = Boolean.parseBoolean(rateLimiterEnabled);
-    if (isRateLimiterEnabled) {
-      RateLimiterChecker.init(rateLimiterHost, rateLimiterPort);
+        log.info("Start:Reloading Indexes");
+        // We iterate over searchers only, since dismaxSearchers share the exact same SearcherManagers
+        for (SearchServer searchServer : searchers.values())
+        {
+            if (searchServer == null)
+                continue;
+            try
+            {
+                searchServer.reloadIndex();
+            }
+            catch (IOException e)
+            {
+                log.severe("Caught exception during reopening of index: " + e.getMessage());
+            }
+        }
+        log.info("End:Reloading Indexes");
+
     }
-  }
 
-  /**
-   * If Index has just been updated (Documents added or removed from existing index) you can use this method to read the
-   * latest documents from the index.
-   */
-  protected void reloadIndexes() {
+    /**
+     * Ensures that admin requests are coming direct from local machine
+     *
+     * @param request
+     * @return
+     */
+    private boolean isRequestFromLocalHost(HttpServletRequest request)
+    {
 
-    log.info("Start:Reloading Indexes");
-    // We iterate over searchers only, since dismaxSearchers share the exact same SearcherManagers
-    for (SearchServer searchServer : searchers.values()) {
-      if (searchServer == null)
-        continue;
-      try {
-        searchServer.reloadIndex();
-      } catch (IOException e) {
-        log.severe("Caught exception during reopening of index: " + e.getMessage());
-      }
+        if (isAdminRemoteEnabled || (request.getRemoteAddr().equals("127.0.0.1"))
+                || (request.getRemoteAddr().equals("0:0:0:0:0:0:0:1")))
+        {
+            log.info("isRequestFromLocalHost:VALID:" + request.getRemoteHost() + "/" + request.getRemoteAddr());
+            return true;
+        }
+        log.info("isRequestFromLocalHost:INVALID:" + request.getRemoteHost() + "/" + request.getRemoteAddr());
+        return false;
     }
-    log.info("End:Reloading Indexes");
 
-  }
+    @Override
+    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
+    {
 
-  /**
-   * Ensures that admin requests are coming direct from local machine
-   * 
-   * @param request
-   * @return
-   */
-  private boolean isRequestFromLocalHost(HttpServletRequest request) {
+        // Check if servlet is initialized ok
+        if (!isServletInitialized)
+        {
+            response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
+                    ErrorMessage.SERVLET_INIT_FAILED.getMsg(initMessage));
+            return;
+        }
+        // Ensure encoding set to UTF8
+        request.setCharacterEncoding(CHARSET);
 
-    if (isAdminRemoteEnabled || (request.getRemoteAddr().equals("127.0.0.1"))
-        || (request.getRemoteAddr().equals("0:0:0:0:0:0:0:1"))) {
-      log.info("isRequestFromLocalHost:VALID:" + request.getRemoteHost() + "/" + request.getRemoteAddr());
-      return true;
-    }
-    log.info("isRequestFromLocalHost:INVALID:" + request.getRemoteHost() + "/" + request.getRemoteAddr());
-    return false;
-  }
+        // Force initialization of search server should be called when index have been replaced by new indexes
+        String init = request.getParameter(RequestParameter.INIT.getName());
+        if (init != null)
+        {
+            log.info("Checking init request");
+            if (isRequestFromLocalHost(request))
+            {
+                init(init.equals("mmap"));
+                response.setCharacterEncoding(CHARSET);
+                response.setContentType("text/plain; charset=UTF-8; charset=UTF-8");
+                response.getWriter().println("Indexes Loaded:");
+                response.getWriter().close();
+                return;
+            } else
+            {
+                response.sendError(HttpServletResponse.SC_FORBIDDEN);
+                return;
+            }
 
-  @Override
-  protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
+        }
 
-    // Check if servlet is initialized ok
-    if (!isServletInitialized) {
-      response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
-          ErrorMessage.SERVLET_INIT_FAILED.getMsg(initMessage));
-      return;
-    }
-    // Ensure encoding set to UTF8
-    request.setCharacterEncoding(CHARSET);
+        // Enabled/Disable Rate Limiter
+        String rate = request.getParameter(RequestParameter.RATE.getName());
+        if (rate != null)
+        {
+            log.info("Checking rate request");
+            if (isRequestFromLocalHost(request))
+            {
+                initRateLimiter(rate);
+                response.setCharacterEncoding(CHARSET);
+                response.setContentType("text/plain; charset=UTF-8; charset=UTF-8");
+                response.getWriter().println("Rate Limiter:" + rate);
+                response.getWriter().close();
+                return;
+            } else
+            {
+                response.sendError(HttpServletResponse.SC_FORBIDDEN);
+                return;
+            }
+        }
 
-    // Force initialization of search server should be called when index have been replaced by new indexes
-    String init = request.getParameter(RequestParameter.INIT.getName());
-    if (init != null) {
-      log.info("Checking init request");
-      if (isRequestFromLocalHost(request)) {
-        init(init.equals("mmap"));
-        response.setCharacterEncoding(CHARSET);
-        response.setContentType("text/plain; charset=UTF-8; charset=UTF-8");
-        response.getWriter().println("Indexes Loaded:");
-        response.getWriter().close();
-        return;
-      } else {
-        response.sendError(HttpServletResponse.SC_FORBIDDEN);
-        return;
-      }
+        // Reopen the indexes in an efficient way when existing indexes have been updated (not replaced)
+        String reloadIndexes = request.getParameter(RequestParameter.RELOAD_INDEXES.getName());
+        if (reloadIndexes != null)
+        {
+            log.info("Checking reloadindex request");
+            if (isRequestFromLocalHost(request))
+            {
+                reloadIndexes();
+                response.setCharacterEncoding(CHARSET);
+                response.setContentType("text/plain; charset=UTF-8; charset=UTF-8");
+                response.getWriter().println("Indexes Reloaded");
+                response.getWriter().close();
+                return;
+            } else
+            {
+                response.sendError(HttpServletResponse.SC_FORBIDDEN);
+                return;
+            }
+        }
 
-    }
+        // If we receive Count Parameter then we just return a count immediately, the options are the same as for the type
+        // parameter
+        String count = request.getParameter(RequestParameter.COUNT.getName());
+        if (count != null)
+        {
+            log.info("Checking count request");
+            ResourceType resourceType = ResourceType.getValue(count);
+            if (resourceType == null)
+            {
+                response.sendError(HttpServletResponse.SC_BAD_REQUEST, ErrorMessage.UNKNOWN_COUNT_TYPE.getMsg(count));
+                return;
+            }
 
-    // Enabled/Disable Rate Limiter
-    String rate = request.getParameter(RequestParameter.RATE.getName());
-    if (rate != null) {
-      log.info("Checking rate request");
-      if (isRequestFromLocalHost(request)) {
-        initRateLimiter(rate);
-        response.setCharacterEncoding(CHARSET);
-        response.setContentType("text/plain; charset=UTF-8; charset=UTF-8");
-        response.getWriter().println("Rate Limiter:" + rate);
-        response.getWriter().close();
-        return;
-      } else {
-        response.sendError(HttpServletResponse.SC_FORBIDDEN);
-        return;
-      }
-    }
+            SearchServer searchServerCount = searchers.get(resourceType);
+            response.setCharacterEncoding(CHARSET);
+            response.setContentType("text/plain; charset=UTF-8; charset=UTF-8");
+            response.getWriter().println(searchServerCount.getCount());
+            response.getWriter().close();
+            return;
+        }
 
-    // Reopen the indexes in an efficient way when existing indexes have been updated (not replaced)
-    String reloadIndexes = request.getParameter(RequestParameter.RELOAD_INDEXES.getName());
-    if (reloadIndexes != null) {
-      log.info("Checking reloadindex request");
-      if (isRequestFromLocalHost(request)) {
-        reloadIndexes();
-        response.setCharacterEncoding(CHARSET);
-        response.setContentType("text/plain; charset=UTF-8; charset=UTF-8");
-        response.getWriter().println("Indexes Reloaded");
-        response.getWriter().close();
-        return;
-      } else {
-        response.sendError(HttpServletResponse.SC_FORBIDDEN);
-        return;
-      }
-    }
+        // If they have entered nothing, redirect to them the Musicbrainz Search Page
+        if (request.getParameterMap().size() == 0)
+        {
+            response.sendRedirect(searchWebPage);
+            return;
+        }
 
-    // If we receive Count Parameter then we just return a count immediately, the options are the same as for the type
-    // parameter
-    String count = request.getParameter(RequestParameter.COUNT.getName());
-    if (count != null) {
-      log.info("Checking count request");
-      ResourceType resourceType = ResourceType.getValue(count);
-      if (resourceType == null) {
-        response.sendError(HttpServletResponse.SC_BAD_REQUEST, ErrorMessage.UNKNOWN_COUNT_TYPE.getMsg(count));
-        return;
-      }
+        // Must be a type parameter and must be type ALL or map to a valid resource type
+        String type = request.getParameter(RequestParameter.TYPE.getName());
+        if (type == null)
+        {
+            response.sendError(HttpServletResponse.SC_BAD_REQUEST, ErrorMessage.UNKNOWN_RESOURCE_TYPE.getMsg("none"));
+        }
 
-      SearchServer searchServerCount = searchers.get(resourceType);
-      response.setCharacterEncoding(CHARSET);
-      response.setContentType("text/plain; charset=UTF-8; charset=UTF-8");
-      response.getWriter().println(searchServerCount.getCount());
-      response.getWriter().close();
-      return;
-    }
+        // V1 Compatibility
+        if (type.equals(TYPE_TRACK))
+        {
+            type = ResourceType.RECORDING.getName();
+        }
 
-    // If they have entered nothing, redirect to them the Musicbrainz Search Page
-    if (request.getParameterMap().size() == 0) {
-      response.sendRedirect(searchWebPage);
-      return;
-    }
+        ResourceType resourceType = null;
+        if (!type.equalsIgnoreCase(TYPE_ALL))
+        {
+            resourceType = ResourceType.getValue(type);
+            if (resourceType == null)
+            {
+                response.sendError(HttpServletResponse.SC_BAD_REQUEST, ErrorMessage.UNKNOWN_RESOURCE_TYPE.getMsg(type));
+                return;
+            }
+        } else if (!isSearchAllEnabled)
+        {
+            response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
+                    ErrorMessage.INDEX_NOT_AVAILABLE_FOR_TYPE.getMsg(TYPE_ALL));
+        }
 
-    // Must be a type parameter and must be type ALL or map to a valid resource type
-    String type = request.getParameter(RequestParameter.TYPE.getName());
-    if (type == null) {
-      response.sendError(HttpServletResponse.SC_BAD_REQUEST, ErrorMessage.UNKNOWN_RESOURCE_TYPE.getMsg("none"));
-    }
+        if (isRateLimiterEnabled)
+        {
+            RateLimiterChecker.RateLimiterResponse rateLimiterResponse = RateLimiterChecker.checkRateLimiter(request);
+            if (!rateLimiterResponse.isValid())
+            {
+                if (rateLimiterResponse.getHeaderMsg() != null)
+                {
+                    response.setHeader(RateLimiterChecker.HEADER_RATE_LIMITED, rateLimiterResponse.getHeaderMsg());
+                }
+                response.sendError(HttpServletResponse.SC_SERVICE_UNAVAILABLE, rateLimiterResponse.getMsg());
+                return;
+            }
+        }
 
-    // V1 Compatibility
-    if (type.equals(TYPE_TRACK)) {
-      type = ResourceType.RECORDING.getName();
-    }
+        String query = request.getParameter(RequestParameter.QUERY.getName());
+        if (query == null || query.isEmpty())
+        {
+            response.sendError(HttpServletResponse.SC_BAD_REQUEST, ErrorMessage.NO_QUERY_PARAMETER.getMsg());
+            return;
+        }
 
-    ResourceType resourceType = null;
-    if (!type.equalsIgnoreCase(TYPE_ALL)) {
-      resourceType = ResourceType.getValue(type);
-      if (resourceType == null) {
-        response.sendError(HttpServletResponse.SC_BAD_REQUEST, ErrorMessage.UNKNOWN_RESOURCE_TYPE.getMsg(type));
-        return;
-      }
-    } else if (!isSearchAllEnabled) {
-      response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
-          ErrorMessage.INDEX_NOT_AVAILABLE_FOR_TYPE.getMsg(TYPE_ALL));
-    }
+        // Response Format, first defined by fmt parameter, if not set defined by accept header, if not set default
+        // to Xml. Note if accept header set to json this will set format to RESPONSE_JSON_NEW not RESPONSE_JSON (the
+        // old internal format)
+        String responseFormat = request.getParameter(RequestParameter.FORMAT.getName());
+        if (responseFormat == null || responseFormat.isEmpty())
+        {
 
-    if (isRateLimiterEnabled) {
-      RateLimiterChecker.RateLimiterResponse rateLimiterResponse = RateLimiterChecker.checkRateLimiter(request);
-      if (!rateLimiterResponse.isValid()) {
-        if (rateLimiterResponse.getHeaderMsg() != null) {
-          response.setHeader(RateLimiterChecker.HEADER_RATE_LIMITED, rateLimiterResponse.getHeaderMsg());
+            Enumeration<String> headers = request.getHeaders("Accept");
+            while (headers.hasMoreElements())
+            {
+                String nextHeader = headers.nextElement();
+                if (nextHeader.equals("application/json"))
+                {
+                    responseFormat = RESPONSE_JSON_NEW;
+                    break;
+                }
+            }
+            // Default to xml if not provided
+            if (responseFormat == null)
+            {
+                responseFormat = RESPONSE_XML;
+            }
         }
-        response.sendError(HttpServletResponse.SC_SERVICE_UNAVAILABLE, rateLimiterResponse.getMsg());
-        return;
-      }
-    }
 
-    String query = request.getParameter(RequestParameter.QUERY.getName());
-    if (query == null || query.isEmpty()) {
-      response.sendError(HttpServletResponse.SC_BAD_REQUEST, ErrorMessage.NO_QUERY_PARAMETER.getMsg());
-      return;
-    }
+        String responseVersion = request.getParameter(RequestParameter.VERSION.getName());
+        if (responseVersion == null || responseVersion.isEmpty())
+        {
+            responseVersion = WS_VERSION_2;
+        }
 
-    // Response Format, first defined by fmt parameter, if not set defined by accept header, if not set default
-    // to Xml. Note if accept header set to json this will set format to RESPONSE_JSON_NEW not RESPONSE_JSON (the
-    // old internal format)
-    String responseFormat = request.getParameter(RequestParameter.FORMAT.getName());
-    if (responseFormat == null || responseFormat.isEmpty()) {
+        Integer offset = DEFAULT_OFFSET;
+        String strOffset = request.getParameter(RequestParameter.OFFSET.getName());
+        if (strOffset != null && !strOffset.isEmpty())
+        {
+            offset = new Integer(strOffset);
+        }
 
-      Enumeration<String> headers = request.getHeaders("Accept");
-      while (headers.hasMoreElements()) {
-        String nextHeader = headers.nextElement();
-        if (nextHeader.equals("application/json")) {
-          responseFormat = RESPONSE_JSON_NEW;
-          break;
+        Integer limit = DEFAULT_MATCHES_LIMIT;
+        String strLimit = request.getParameter(RequestParameter.LIMIT.getName());
+        String strMax = request.getParameter(RequestParameter.MAX.getName());
+        // Used by webservice
+        if (strLimit != null && !strLimit.isEmpty())
+        {
+            limit = new Integer(strLimit);
+            if (limit > MAX_MATCHES_LIMIT)
+            {
+                limit = MAX_MATCHES_LIMIT;
+            }
         }
-      }
-      // Default to xml if not provided
-      if (responseFormat == null) {
-        responseFormat = RESPONSE_XML;
-      }
-    }
+        // Used by web search (although entered as limit on website then converted to max !)
+        // TODO perhaps could be simplified
+        else if (strMax != null && !strMax.isEmpty())
+        {
+            limit = new Integer(strMax);
+            if (limit > MAX_MATCHES_LIMIT)
+            {
+                limit = MAX_MATCHES_LIMIT;
+            }
+        }
 
-    String responseVersion = request.getParameter(RequestParameter.VERSION.getName());
-    if (responseVersion == null || responseVersion.isEmpty()) {
-      responseVersion = WS_VERSION_2;
-    }
+        boolean isExplain = false;
+        String strIsExplain = request.getParameter(RequestParameter.EXPLAIN.getName());
+        if (strIsExplain != null && strIsExplain.equals("true"))
+        {
+            isExplain = true;
+        }
 
-    Integer offset = DEFAULT_OFFSET;
-    String strOffset = request.getParameter(RequestParameter.OFFSET.getName());
-    if (strOffset != null && !strOffset.isEmpty()) {
-      offset = new Integer(strOffset);
-    }
+        boolean isPretty = false;
+        String strIsPretty = request.getParameter(RequestParameter.PRETTY.getName());
+        if (strIsPretty != null && strIsPretty.equals("true"))
+        {
+            isPretty = true;
+        }
 
-    Integer limit = DEFAULT_MATCHES_LIMIT;
-    String strLimit = request.getParameter(RequestParameter.LIMIT.getName());
-    String strMax = request.getParameter(RequestParameter.MAX.getName());
-    // Used by webservice
-    if (strLimit != null && !strLimit.isEmpty()) {
-      limit = new Integer(strLimit);
-      if (limit > MAX_MATCHES_LIMIT) {
-        limit = MAX_MATCHES_LIMIT;
-      }
-    }
-    // Used by web search (although entered as limit on website then converted to max !)
-    // TODO perhaps could be simplified
-    else if (strMax != null && !strMax.isEmpty()) {
-      limit = new Integer(strMax);
-      if (limit > MAX_MATCHES_LIMIT) {
-        limit = MAX_MATCHES_LIMIT;
-      }
-    }
+        boolean isDismax = false;
+        String strIsDismax = request.getParameter(RequestParameter.DISMAX.getName());
+        if (strIsDismax != null && strIsDismax.equals("true"))
+        {
+            isDismax = true;
+        }
 
-    boolean isExplain = false;
-    String strIsExplain = request.getParameter(RequestParameter.EXPLAIN.getName());
-    if (strIsExplain != null && strIsExplain.equals("true")) {
-      isExplain = true;
+        try
+        {
+            if (resourceType != null)
+            {
+                // log.log(Level.SEVERE,"Query sent"+query);
+                doSearch(response, resourceType, query, isDismax, isExplain, isPretty, offset, limit, responseFormat,
+                        responseVersion);
+            } else
+            {
+                doAllSearch(response, query, isDismax, offset, limit, responseFormat, isPretty);
+            }
+        }
+        catch (ParseException pe)
+        {
+            response.sendError(HttpServletResponse.SC_BAD_REQUEST, ErrorMessage.UNABLE_TO_PARSE_SEARCH.getMsg(query));
+            return;
+        }
+        catch (Exception e)
+        {
+            log.log(Level.SEVERE, e.getMessage(), e);
+            response.sendError(HttpServletResponse.SC_BAD_REQUEST, e.getMessage());
+            return;
+        }
     }
 
-    boolean isPretty = false;
-    String strIsPretty = request.getParameter(RequestParameter.PRETTY.getName());
-    if (strIsPretty != null && strIsPretty.equals("true")) {
-      isPretty = true;
-    }
+    /**
+     * Normal Search over one index
+     *
+     * @param response
+     * @param resourceType
+     * @param query
+     * @param isDismax
+     * @param isPretty
+     * @param offset
+     * @param limit
+     * @param responseFormat
+     * @param responseVersion @throws ParseException
+     * @throws IOException
+     */
+    private void doSearch(HttpServletResponse response, ResourceType resourceType, String query, boolean isDismax,
+                          boolean isExplain, boolean isPretty, Integer offset, Integer limit, String responseFormat, String responseVersion)
+            throws ParseException, IOException
+    {
 
-    boolean isDismax = false;
-    String strIsDismax = request.getParameter(RequestParameter.DISMAX.getName());
-    if (strIsDismax != null && strIsDismax.equals("true")) {
-      isDismax = true;
-    }
+        SearchServer searchServer;
+        if (isDismax)
+        {
+            searchServer = dismaxSearchers.get(resourceType);
+        } else
+        {
+            searchServer = searchers.get(resourceType);
+        }
 
-    try {
-      if (resourceType != null) {
-        // log.log(Level.SEVERE,"Query sent"+query);
-        doSearch(response, resourceType, query, isDismax, isExplain, isPretty, offset, limit, responseFormat,
-            responseVersion);
-      } else {
-        doAllSearch(response, query, isDismax, offset, limit, responseFormat, isPretty);
-      }
-    } catch (ParseException pe) {
-      response.sendError(HttpServletResponse.SC_BAD_REQUEST, ErrorMessage.UNABLE_TO_PARSE_SEARCH.getMsg(query));
-      return;
-    } catch (Exception e) {
-      log.log(Level.SEVERE, e.getMessage(), e);
-      response.sendError(HttpServletResponse.SC_BAD_REQUEST, e.getMessage());
-      return;
-    }
-  }
+        if (searchServer == null)
+        {
+            response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
+                    ErrorMessage.INDEX_NOT_AVAILABLE_FOR_TYPE.getMsg(resourceType));
+            return;
+        }
 
-  /**
-   * Normal Search over one index
-   * 
-   * @param response
-   * @param resourceType
-   * @param query
-   * @param isDismax
-   * @param isPretty
-   * @param offset
-   * @param limit
-   * @param responseFormat
-   * @param responseVersion @throws ParseException
-   * @throws IOException
-   */
-  private void doSearch(HttpServletResponse response, ResourceType resourceType, String query, boolean isDismax,
-      boolean isExplain, boolean isPretty, Integer offset, Integer limit, String responseFormat, String responseVersion)
-          throws ParseException, IOException {
+        if (isExplain)
+        {
+            String explainationOutput = searchServer.explain(query, offset, limit);
+            response.setCharacterEncoding(CHARSET);
+            response.setContentType("text/html");
+            response.getWriter().println(explainationOutput);
+            response.getWriter().close();
+            return;
+        }
 
-    SearchServer searchServer;
-    if (isDismax) {
-      searchServer = dismaxSearchers.get(resourceType);
-    } else {
-      searchServer = searchers.get(resourceType);
-    }
+        Results results = searchServer.search(query, offset, limit);
+        org.musicbrainz.search.servlet.ResultsWriter writer = searchServer.getWriter(responseVersion);
 
-    if (searchServer == null) {
-      response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
-          ErrorMessage.INDEX_NOT_AVAILABLE_FOR_TYPE.getMsg(resourceType));
-      return;
-    }
+        if (writer == null)
+        {
+            response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
+                    ErrorMessage.NO_HANDLER_FOR_TYPE_AND_FORMAT.getMsg(resourceType, responseFormat));
+            return;
+        }
+        response.setCharacterEncoding(CHARSET);
+        if (responseFormat.equals(RESPONSE_XML))
+        {
+            response.setContentType(writer.getMimeType());
+        } else
+        {
+            response.setContentType(((ResultsWriter) writer).getJsonMimeType());
+        }
 
-    if (isExplain) {
-      String explainationOutput = searchServer.explain(query, offset, limit);
-      response.setCharacterEncoding(CHARSET);
-      response.setContentType("text/html");
-      response.getWriter().println(explainationOutput);
-      response.getWriter().close();
-      return;
-    }
+        if (writer.getLastUpdateDate() != null)
+        {
+            response.setDateHeader("Last-Modified", writer.getLastUpdateDate().getTime());
+        }
 
-    Results results = searchServer.search(query, offset, limit);
-    org.musicbrainz.search.servlet.ResultsWriter writer = searchServer.getWriter(responseVersion);
-
-    if (writer == null) {
-      response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
-          ErrorMessage.NO_HANDLER_FOR_TYPE_AND_FORMAT.getMsg(resourceType, responseFormat));
-      return;
+        PrintWriter out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(response.getOutputStream(), CHARSET)));
+        writer.write(out, results, responseFormat, isPretty);
+        out.close();
     }
-    response.setCharacterEncoding(CHARSET);
-    if (responseFormat.equals(RESPONSE_XML)) {
-      response.setContentType(writer.getMimeType());
-    } else {
-      response.setContentType(((ResultsWriter) writer).getJsonMimeType());
-    }
 
-    if (writer.getLastUpdateDate() != null) {
-      response.setDateHeader("Last-Modified", writer.getLastUpdateDate().getTime());
-    }
+    /**
+     * Search over multiple different indexes and return merged result
+     *
+     * @param response
+     * @param query
+     * @param isDismax
+     * @param offset
+     * @param limit
+     * @param responseFormat @throws ParseException
+     * @param isPretty
+     * @throws IOException
+     */
+    private void doAllSearch(HttpServletResponse response, String query, boolean isDismax, Integer offset, Integer limit,
+                             String responseFormat, boolean isPretty) throws Exception
+    {
 
-    PrintWriter out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(response.getOutputStream(), CHARSET)));
-    writer.write(out, results, responseFormat, isPretty);
-    out.close();
-  }
+        SearchServer artistSearch = isDismax ? dismaxSearchers.get(ResourceType.ARTIST) : searchers
+                .get(ResourceType.ARTIST);
+        SearchServer releaseSearch = isDismax ? dismaxSearchers.get(ResourceType.RELEASE) : searchers
+                .get(ResourceType.RELEASE);
+        SearchServer releaseGroupSearch = isDismax ? dismaxSearchers.get(ResourceType.RELEASE_GROUP) : searchers
+                .get(ResourceType.RELEASE_GROUP);
+        SearchServer labelSearch = isDismax ? dismaxSearchers.get(ResourceType.LABEL) : searchers
+                .get(ResourceType.LABEL);
+        SearchServer recordingSearch = isDismax ? dismaxSearchers.get(ResourceType.RECORDING) : searchers
+                .get(ResourceType.RECORDING);
+        SearchServer workSearch = isDismax ? dismaxSearchers.get(ResourceType.WORK) : searchers
+                .get(ResourceType.WORK);
 
-  /**
-   * Search over multiple different indexes and return merged result
-   * 
-   * @param response
-   * @param query
-   * @param isDismax
-   * @param offset
-   * @param limit
-   * @param responseFormat @throws ParseException
-   * @param isPretty
-   * @throws IOException
-   */
-  private void doAllSearch(HttpServletResponse response, String query, boolean isDismax, Integer offset, Integer limit,
-      String responseFormat, boolean isPretty) throws Exception {
+        Collection<Callable<Results>> searches = new ArrayList<Callable<Results>>();
+        searches.add(new CallableSearch(artistSearch, query, offset, limit));
+        searches.add(new CallableSearch(releaseSearch, query, offset, limit));
+        searches.add(new CallableSearch(releaseGroupSearch, query, offset, limit));
+        searches.add(new CallableSearch(labelSearch, query, offset, limit));
+        searches.add(new CallableSearch(recordingSearch, query, offset, limit));
+        searches.add(new CallableSearch(workSearch, query, offset, limit));
 
-    SearchServer artistSearch = isDismax ? dismaxSearchers.get(ResourceType.ARTIST) : searchers
-        .get(ResourceType.ARTIST);
-    SearchServer releaseSearch = isDismax ? dismaxSearchers.get(ResourceType.RELEASE) : searchers
-        .get(ResourceType.RELEASE);
-    SearchServer releaseGroupSearch = isDismax ? dismaxSearchers.get(ResourceType.RELEASE_GROUP) : searchers
-        .get(ResourceType.RELEASE_GROUP);
-    SearchServer labelSearch = isDismax ? dismaxSearchers.get(ResourceType.LABEL) : searchers
-        .get(ResourceType.LABEL);
-    SearchServer recordingSearch = isDismax ? dismaxSearchers.get(ResourceType.RECORDING) : searchers
-        .get(ResourceType.RECORDING);
-    SearchServer workSearch = isDismax ? dismaxSearchers.get(ResourceType.WORK) : searchers
-        .get(ResourceType.WORK);
+        // Run each search in parallel then merge results
+        List<Future<Results>> results = es.invokeAll(searches);
+        Results allResults = new Results();
+        // Results are returned in same order as they were submitted
+        Results artistResults = results.get(0).get();
+        Results releaseResults = results.get(1).get();
+        Results releaseGroupResults = results.get(2).get();
+        Results labelResults = results.get(3).get();
+        Results recordingResults = results.get(4).get();
+        Results workResults = results.get(5).get();
 
-    Collection<Callable<Results>> searches = new ArrayList<Callable<Results>>();
-    searches.add(new CallableSearch(artistSearch, query, offset, limit));
-    searches.add(new CallableSearch(releaseSearch, query, offset, limit));
-    searches.add(new CallableSearch(releaseGroupSearch, query, offset, limit));
-    searches.add(new CallableSearch(labelSearch, query, offset, limit));
-    searches.add(new CallableSearch(recordingSearch, query, offset, limit));
-    searches.add(new CallableSearch(workSearch, query, offset, limit));
+        AllWriter writer = new AllWriter(artistResults, releaseResults, releaseGroupResults, labelResults,
+                recordingResults, workResults);
+        response.setCharacterEncoding(CHARSET);
 
-    // Run each search in parallel then merge results
-    List<Future<Results>> results = es.invokeAll(searches);
-    Results allResults = new Results();
-    // Results are returned in same order as they were submitted
-    Results artistResults = results.get(0).get();
-    Results releaseResults = results.get(1).get();
-    Results releaseGroupResults = results.get(2).get();
-    Results labelResults = results.get(3).get();
-    Results recordingResults = results.get(4).get();
-    Results workResults = results.get(5).get();
+        if (responseFormat.equals(RESPONSE_XML))
+        {
+            response.setContentType(writer.getMimeType());
+        } else
+        {
+            response.setContentType(writer.getJsonMimeType());
+        }
 
-    AllWriter writer = new AllWriter(artistResults, releaseResults, releaseGroupResults, labelResults,
-        recordingResults, workResults);
-    response.setCharacterEncoding(CHARSET);
+        if (writer.getLastUpdateDate() != null)
+        {
+            response.setDateHeader("Last-Modified", writer.getLastUpdateDate().getTime());
+        }
 
-    if (responseFormat.equals(RESPONSE_XML)) {
-      response.setContentType(writer.getMimeType());
-    } else {
-      response.setContentType(writer.getJsonMimeType());
+        PrintWriter out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(response.getOutputStream(), CHARSET)));
+        writer.write(out, allResults, responseFormat, isPretty);
+        out.close();
     }
 
-    if (writer.getLastUpdateDate() != null) {
-      response.setDateHeader("Last-Modified", writer.getLastUpdateDate().getTime());
-    }
+    // Used by doAllSearch()
+    class CallableSearch implements Callable<Results>
+    {
 
-    PrintWriter out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(response.getOutputStream(), CHARSET)));
-    writer.write(out, allResults, responseFormat, isPretty);
-    out.close();
-  }
+        private final SearchServer searchServer;
+        private final String query;
+        private final Integer offset;
+        private final Integer limit;
 
-  // Used by doAllSearch()
-  class CallableSearch implements Callable<Results> {
+        public CallableSearch(SearchServer searchServer, String query, Integer offset, Integer limit)
+        {
+            this.searchServer = searchServer;
+            this.query = query;
+            this.offset = offset;
+            this.limit = limit;
+        }
 
-    private final SearchServer searchServer;
-    private final String query;
-    private final Integer offset;
-    private final Integer limit;
+        @Override
+        public Results call() throws Exception
+        {
+            return searchServer.search(query, offset, limit);
+        }
 
-    public CallableSearch(SearchServer searchServer, String query, Integer offset, Integer limit) {
-      this.searchServer = searchServer;
-      this.query = query;
-      this.offset = offset;
-      this.limit = limit;
     }
-
-    @Override
-    public Results call() throws Exception {
-      return searchServer.search(query, offset, limit);
-    }
-
-  }
 }

Modified: search_server/trunk/servlet/src/test/java/org/musicbrainz/search/servlet/FindAnnotationTest.java
===================================================================
--- search_server/trunk/servlet/src/test/java/org/musicbrainz/search/servlet/FindAnnotationTest.java	2013-02-27 06:17:07 UTC (rev 13630)
+++ search_server/trunk/servlet/src/test/java/org/musicbrainz/search/servlet/FindAnnotationTest.java	2013-02-27 07:30:09 UTC (rev 13631)
@@ -209,7 +209,7 @@
     org.musicbrainz.search.servlet.mmd2.ResultsWriter writer = ss.getMmd2Writer();
     StringWriter sw = new StringWriter();
     PrintWriter pr = new PrintWriter(sw);
-    writer.write(pr, res);
+    writer.write(pr, res, SearchServerServlet.RESPONSE_XML, true);
     pr.close();
 
     String output = sw.toString();