// This test has set response to JSON and pass StringHandle with format as JSON, expectint it to
  // work, logged an issue 82
  @Test
  public void testBulkSearchSQDwithResponseFormatandStringHandle() throws Exception {
    loadJSONDocuments();
    JSONDocumentManager docMgr = client.newJSONDocumentManager();

    QueryManager queryMgr = client.newQueryManager();
    StructuredQueryBuilder qb = new StructuredQueryBuilder();
    StructuredQueryDefinition qd = qb.and(qb.term("dog1", "dog11"));
    queryMgr.search(qd, new SearchHandle());

    docMgr.setNonDocumentFormat(Format.JSON);
    docMgr.setSearchView(QueryView.METADATA);
    docMgr.setMetadataCategories(Metadata.PERMISSIONS);

    StringHandle results = new StringHandle().withFormat(Format.JSON);
    DocumentPage page = docMgr.search(qd, 1, results);
    DocumentMetadataHandle mh = new DocumentMetadataHandle();
    while (page.hasNext()) {
      DocumentRecord rec = page.next();
      validateRecord(rec, Format.JSON);
      docMgr.readMetadata(rec.getUri(), mh);
      assertTrue("Records has permissions? ", mh.getPermissions().containsKey("flexrep-eval"));
      assertTrue("Record has collections ?", mh.getCollections().isEmpty());
    }
    assertFalse("Search handle contains", results.get().isEmpty());
  }
  @Test
  public void testPOJOSearchWithoutSearchHandle() {
    PojoRepository<Artifact, Long> products = client.newPojoRepository(Artifact.class, Long.class);
    PojoPage<Artifact> p;
    this.loadSimplePojos(products);
    QueryManager queryMgr = client.newQueryManager();
    StringQueryDefinition qd = queryMgr.newStringDefinition();
    qd.setCriteria("Widgets");

    products.setPageLength(11);
    p = products.search(qd, 1);
    assertEquals("total no of pages", 5, p.getTotalPages());
    System.out.println(p.getTotalPages());
    long pageNo = 1, count = 0;
    do {
      count = 0;

      p = products.search(qd, pageNo);

      while (p.iterator().hasNext()) {
        Artifact a = p.iterator().next();
        validateArtifact(a);
        assertTrue("Artifact Id is odd", a.getId() % 2 != 0);
        assertTrue(
            "Company name contains widgets", a.getManufacturer().getName().contains("Widgets"));
        count++;
        //				System.out.println(a.getId()+" "+a.getManufacturer().getName() +"  "+count);
      }
      assertEquals("Page size", count, p.size());
      pageNo = pageNo + p.getPageSize();
    } while (!p.isLastPage() && pageNo < p.getTotalSize());
    assertEquals("page number after the loop", 5, p.getPageNumber());
    assertEquals("total no of pages", 5, p.getTotalPages());
  }
    public DictionaryManager(DatabaseClient client) {
      super();

      // a Resource Manager must be initialized by a Database Client
      client.init(NAME, this);

      // the Dictionary Manager delegates some services to a document manager
      docMgr = client.newXMLDocumentManager();
    }
  @Test(expected = ClassCastException.class)
  public void testPOJOqbeSearchWithSearchHandle() {
    PojoRepository<Artifact, Long> products = client.newPojoRepository(Artifact.class, Long.class);
    PojoPage<Artifact> p;
    this.loadSimplePojos(products);

    QueryManager queryMgr = client.newQueryManager();
    String queryAsString =
        "{\"$query\":{"
            + "\"$and\":[{\"inventory\":{\"$gt\":1010}},{\"inventory\":{\"$le\":1110}}]"
            + ",\"$filtered\": true}}";
    System.out.println(queryAsString);
    PojoQueryDefinition qd =
        (PojoQueryDefinition)
            queryMgr.newRawQueryByExampleDefinition(
                new StringHandle(queryAsString).withFormat(Format.JSON));
    qd.setCollections("even");
    SearchHandle results = new SearchHandle();
    products.setPageLength(10);
    p = products.search(qd, 1, results);
    assertEquals("total no of pages", 5, p.getTotalPages());
    System.out.println(p.getTotalPages());
    //		System.out.println(results.getMetrics().getQueryResolutionTime());
    long pageNo = 1, count = 0;
    do {
      count = 0;
      p = products.search(qd, pageNo, results);

      while (p.iterator().hasNext()) {
        Artifact a = p.iterator().next();
        validateArtifact(a);
        assertTrue(
            "Enventory lies between 1010 to 1110",
            a.getInventory() > 1010 && a.getInventory() <= 1110);
        assertTrue("Artifact Id is even", a.getId() % 2 == 0);
        assertTrue("Company name contains Acme", a.getManufacturer().getName().contains("Acme"));
        count++;
        //				System.out.println(a.getId()+" "+a.getManufacturer().getName() +"  "+count);
      }
      assertEquals("Page size", count, p.size());
      pageNo = pageNo + p.getPageSize();
      MatchDocumentSummary[] mds = results.getMatchResults();
      assertEquals("Size of the results summary", 10, mds.length);
      for (MatchDocumentSummary md : mds) {
        assertTrue("every uri should contain the class name", md.getUri().contains("Artifact"));
      }
      String[] facetNames = results.getFacetNames();
      for (String fname : facetNames) {
        System.out.println(fname);
      }
      //			assertEquals("Total results from search handle ",50,results.getTotalResults());
      //			assertTrue("Search Handle metric results ",results.getMetrics().getTotalTime()>0);
    } while (!p.isLastPage() && pageNo < p.getTotalSize());
    assertEquals("Page start check", 41, p.getStart());
    assertEquals("page number after the loop", 5, p.getPageNumber());
    assertEquals("total no of pages", 5, p.getTotalPages());
  }
  @Test(expected = ClassCastException.class)
  public void testPOJOCombinedSearchWithJacksonHandle() {
    PojoRepository<Artifact, Long> products = client.newPojoRepository(Artifact.class, Long.class);
    PojoPage<Artifact> p;
    this.loadSimplePojos(products);
    QueryManager queryMgr = client.newQueryManager();
    String queryAsString =
        "{\"search\":{\"query\":{\"and-query\":["
            + "{\"word-constraint-query\":{\"constraint-name\":\"pojo-name-field\", \"text\":\"Acme\"}},"
            + "{\"word-constraint-query\":{\"constraint-name\":\"pojo-name-field\", \"text\":\"special\"}}]},"
            + "\"options\":{\"constraint\":{\"name\":\"pojo-name-field\", \"word\":{\"json-property\":\"name\"}}}"
            + "}}";

    PojoQueryDefinition qd =
        (PojoQueryDefinition)
            queryMgr.newRawCombinedQueryDefinition(
                new StringHandle(queryAsString).withFormat(Format.JSON));
    JacksonHandle results = new JacksonHandle();
    p = products.search(qd, 1, results);
    products.setPageLength(11);
    assertEquals("total no of pages", 1, p.getTotalPages());
    //		System.out.println(p.getTotalPages()+results.get().toString());
    long pageNo = 1, count = 0;
    do {
      count = 0;
      p = products.search(qd, pageNo, results);

      while (p.iterator().hasNext()) {
        Artifact a = p.iterator().next();
        validateArtifact(a);
        count++;
        assertTrue(
            "Manufacture name starts with acme", a.getManufacturer().getName().contains("Acme"));
        assertTrue("Artifact name contains", a.getName().contains("special"));
      }
      assertEquals("Page size", count, p.size());
      pageNo = pageNo + p.getPageSize();

      assertEquals(
          "Page start from search handls vs page methods",
          results.get().get("start").asLong(),
          p.getStart());
      assertEquals(
          "Format in the search handle",
          "json",
          results.get().withArray("results").get(1).path("format").asText());
      assertTrue(
          "Uri in search handle contains Artifact",
          results.get().withArray("results").get(1).path("uri").asText().contains("Artifact"));
      //			System.out.println(results.get().toString());
    } while (!p.isLastPage() && pageNo < p.getTotalSize());
    assertFalse("search handle has metrics", results.get().has("metrics"));
    assertEquals("Total from search handle", 11, results.get().get("total").asInt());
    assertEquals("page number after the loop", 1, p.getPageNumber());
    assertEquals("total no of pages", 1, p.getTotalPages());
  }
  // clean up by deleting the example resource extension
  public static void tearDownExample(
      String host, int port, String user, String password, Authentication authType) {
    DatabaseClient client = DatabaseClientFactory.newClient(host, port, user, password, authType);

    ResourceExtensionsManager resourceMgr =
        client.newServerConfigManager().newResourceExtensionsManager();

    resourceMgr.deleteServices(DictionaryManager.NAME);

    client.release();
  }
 // This test is to verify extract-document-data & extract-path with  selected=exclude option query
 @Test
 public void testExtractDocumentData2() throws Exception {
   this.loadJSONDocuments();
   this.loadXMLDocuments();
   String head = "<search:search xmlns:search=\"http://marklogic.com/appservices/search\">";
   String tail = "</search:search>";
   String qtext4 = "<search:qtext>71 OR dog14</search:qtext>";
   DocumentManager docMgr = client.newDocumentManager();
   QueryManager queryMgr = client.newQueryManager();
   String options =
       "<search:options>"
           + "<search:extract-document-data selected=\"exclude\">"
           + "<search:extract-path>//foo</search:extract-path>"
           + "<search:extract-path>//says</search:extract-path>"
           + "</search:extract-document-data>"
           + "</search:options>";
   // test XML response with extracted XML and JSON matches
   String combinedSearch = head + qtext4 + options + tail;
   RawCombinedQueryDefinition rawCombinedQueryDefinition =
       queryMgr.newRawCombinedQueryDefinition(
           new StringHandle(combinedSearch).withMimetype("application/xml"));
   SearchHandle results = queryMgr.search(rawCombinedQueryDefinition, new SearchHandle());
   MatchDocumentSummary[] summaries = results.getMatchResults();
   assertNotNull(summaries);
   assertEquals(2, summaries.length);
   for (MatchDocumentSummary summary : summaries) {
     ExtractedResult extracted = summary.getExtracted();
     if (Format.XML == summary.getFormat()) {
       // we don't test for kind because it isn't sent in this case
       System.out.println("EXTRACTED Size ==" + extracted.size());
       // TODO:: Bug 33921 also add test to include-with-ancestors
       assertEquals(0, extracted.size());
       //			Document item1 = extracted.next().getAs(Document.class);
       //			assertEquals("This is so foo with a bar 71", item1.getFirstChild().getTextContent());
       continue;
     } else if (Format.JSON == summary.getFormat()) {
       // we don't test for kind because it isn't sent in this case
       assertEquals(1, extracted.size());
       for (ExtractedItem item : extracted) {
         String stringJsonItem = item.getAs(String.class);
         JsonNode nodeJsonItem = item.getAs(JsonNode.class);
         if (nodeJsonItem.has("animal")) {
           assertEquals("{\"animal\":\"dog14\"}", stringJsonItem);
           continue;
         }
         fail("unexpected extracted item:" + stringJsonItem);
       }
       continue;
     }
     fail("unexpected search result:" + summary.getUri());
   }
 }
  // This test is to verify RAW XML structured Query
  @Test
  public void testBulkSearchRawXMLStrucQD() throws Exception {
    //		setAutomaticDirectoryCreation(dbName,"automatic");
    setMaintainLastModified(dbName, true);
    this.loadJSONDocuments();
    this.loadXMLDocuments();
    GenericDocumentManager docMgr = client.newDocumentManager();
    QueryManager queryMgr = client.newQueryManager();
    String rawXMLQuery =
        "<search:query "
            + "xmlns:search='http://marklogic.com/appservices/search'>"
            + " <search:or-query><search:term-query>"
            + "<search:text>bar</search:text>"
            + "</search:term-query>"
            + "<search:term-query>"
            + "<search:text>woof</search:text>"
            + "</search:term-query> </search:or-query>"
            + "</search:query>";
    StringHandle rh = new StringHandle(rawXMLQuery);
    RawStructuredQueryDefinition qd = queryMgr.newRawStructuredQueryDefinition(rh);
    DOMHandle dh = new DOMHandle();
    DocumentPage page = docMgr.search(qd, 1, dh);
    DocumentMetadataHandle mh = new DocumentMetadataHandle();

    int count = 1;
    while (count < 4) {
      page = docMgr.search(qd, count, dh);

      while (page.hasNext()) {
        DocumentRecord rec = page.next();
        if (rec.getMimetype().contains("xml")) {
          validateRecord(rec, Format.XML);
        } else {
          validateRecord(rec, Format.JSON);
        }
        docMgr.readMetadata(rec.getUri(), mh);
        assertTrue("Records has permissions? ", mh.getPermissions().containsKey("flexrep-eval"));
        assertFalse("Record has collections ?", mh.getCollections().isEmpty());
      }
      System.out.println(this.convertXMLDocumentToString(dh.get()));
      assertEquals(
          "Total search results before transaction rollback are ",
          "204",
          dh.get()
              .getElementsByTagNameNS("*", "response")
              .item(0)
              .getAttributes()
              .getNamedItem("total")
              .getNodeValue());
      count++;
    }
  }
  // install the resource extension on the server
  public static void installResourceExtension(
      String host, int port, String user, String password, Authentication authType)
      throws IOException {
    // create the client
    DatabaseClient client = DatabaseClientFactory.newClient(host, port, user, password, authType);

    // use either shortcut or strong typed IO
    installResourceExtensionShortcut(client);
    installResourceExtensionStrongTyped(client);

    // release the client
    client.release();
  }
  // use the resource manager
  public static void useResource(
      String host, int port, String user, String password, Authentication authType)
      throws ResourceNotFoundException, ForbiddenUserException, FailedRequestException {
    // create the client
    DatabaseClient client = DatabaseClientFactory.newClient(host, port, user, password, authType);

    // create the resource extension client
    DictionaryManager dictionaryMgr = new DictionaryManager(client);

    // specify the identifier for the dictionary
    String uri = "/example/metasyn.xml";

    // create the dictionary
    String[] words = {"foo", "bar", "baz", "qux", "quux", "wibble", "wobble", "wubble"};
    dictionaryMgr.createDictionary(uri, words);

    System.out.println("Created a dictionary on the server at " + uri);

    // check the validity of the dictionary
    Document[] list = dictionaryMgr.checkDictionaries(uri);
    if (list == null || list.length == 0)
      System.out.println("Could not check the validity of the dictionary at " + uri);
    else
      System.out.println(
          "Checked the validity of the dictionary at "
              + uri
              + ": "
              + !"invalid".equals(list[0].getDocumentElement().getNodeName()));

    // use a resource service to check the correctness of a word
    String word = "biz";
    if (!dictionaryMgr.isCorrect(word, uri)) {
      System.out.println("Confirmed that '" + word + "' is not in the dictionary at " + uri);

      // use a resource service to look up suggestions
      String[] suggestions = dictionaryMgr.suggest(word, null, null, uri);

      System.out.println("Nearest matches for '" + word + "' in the dictionary at " + uri);
      for (String suggestion : suggestions) {
        System.out.println("    " + suggestion);
      }
    }

    // delete the dictionary
    dictionaryMgr.deleteDictionary(uri);

    // release the client
    client.release();
  }
  // This test is testing SearchView options and search handle
  @Test
  public void testBulkSearchSQDwithJSONResponseFormat() throws Exception {

    loadJSONDocuments();
    JSONDocumentManager docMgr = client.newJSONDocumentManager();

    QueryManager queryMgr = client.newQueryManager();
    StructuredQueryBuilder qb = new StructuredQueryBuilder();
    StructuredQueryDefinition qd = qb.and(qb.term("woof"));
    docMgr.setNonDocumentFormat(Format.JSON);

    docMgr.setSearchView(QueryView.FACETS);
    JacksonHandle jh = new JacksonHandle();
    docMgr.search(qd, 1, jh);

    //		System.out.println(jh.get().toString());
    assertTrue("Searh response has entry for facets", jh.get().has("facets"));
    assertFalse(
        "Searh response has entry for facets",
        jh.get().has("results")); // Issue 84 is tracking this
    assertFalse("Searh response has entry for facets", jh.get().has("metrics"));

    docMgr.setSearchView(QueryView.RESULTS);
    docMgr.search(qd, 1, jh);

    assertFalse("Searh response has entry for facets", jh.get().has("facets"));
    assertTrue("Searh response has entry for facets", jh.get().has("results"));
    assertFalse(
        "Searh response has entry for facets",
        jh.get().has("metrics")); // Issue 84 is tracking this

    docMgr.setSearchView(QueryView.METADATA);
    docMgr.search(qd, 1, jh);

    assertFalse("Searh response has entry for facets", jh.get().has("facets"));
    assertFalse("Searh response has entry for facets", jh.get().has("results"));
    assertTrue("Searh response has entry for facets", jh.get().has("metrics"));

    docMgr.setSearchView(QueryView.ALL);
    docMgr.search(qd, 1, jh);

    assertTrue("Searh response has entry for facets", jh.get().has("facets"));
    assertTrue("Searh response has entry for facets", jh.get().has("results"));
    assertTrue("Searh response has entry for facets", jh.get().has("metrics"));

    queryMgr.setView(QueryView.FACETS);
    queryMgr.search(qd, jh);
    System.out.println(jh.get().toString());
  }
  public static void run(ExampleProperties props) throws IOException {
    System.out.println("example: " + StreamReadWrite.class.getName() + "\n");

    // create the client
    DatabaseClient client =
        DatabaseClientFactory.newClient(
            props.host, props.port, props.adminUser, props.adminPassword, props.authType);

    writeBinaryContent(client);
    readWriteBinaryStream(client);
    readBinaryBuffer(client);

    // release the client
    client.release();
  }
  public static void run(ExampleProperties props) throws IOException {
    System.out.println("example: " + DocumentOutputStream.class.getName());

    final int MAX_BUF = 8192;
    final String FILENAME = "flipper.xml";

    // create the client
    DatabaseClient client =
        DatabaseClientFactory.newClient(
            props.host, props.port, props.writerUser, props.writerPassword, props.authType);

    // create a manager for XML documents
    XMLDocumentManager docMgr = client.newXMLDocumentManager();

    // create an identifier for the document
    String docId = "/example/" + FILENAME;

    // create an anonymous class with a callback method
    OutputStreamSender sender =
        new OutputStreamSender() {
          // the callback receives the output stream
          public void write(OutputStream out) throws IOException {
            // acquire the content
            InputStream docStream = Util.openStream("data" + File.separator + FILENAME);
            if (docStream == null) throw new IOException("Could not read document example");

            // copy content to the output stream
            byte[] buf = new byte[MAX_BUF];
            int byteCount = 0;
            while ((byteCount = docStream.read(buf)) != -1) {
              out.write(buf, 0, byteCount);
            }
          }
        };

    // create a handle for writing the content
    OutputStreamHandle handle = new OutputStreamHandle(sender);

    // write the document content
    docMgr.write(docId, handle);

    System.out.println("Wrote /example/" + FILENAME + " content");

    tearDownExample(docMgr, docId);

    // release the client
    client.release();
  }
  public static void installResourceExtensionStrongTyped(DatabaseClient client) throws IOException {
    // create a manager for resource extensions
    ResourceExtensionsManager resourceMgr =
        client.newServerConfigManager().newResourceExtensionsManager();

    // specify metadata about the resource extension
    ExtensionMetadata metadata = new ExtensionMetadata();
    metadata.setTitle("Spelling Dictionary Resource Services");
    metadata.setDescription("This plugin supports spelling dictionaries");
    metadata.setProvider("MarkLogic");
    metadata.setVersion("0.1");

    // acquire the resource extension source code
    InputStream sourceStream =
        Util.openStream("scripts" + File.separator + DictionaryManager.NAME + ".xqy");
    if (sourceStream == null) throw new IOException("Could not read example resource extension");

    // create a handle on the extension source code
    InputStreamHandle handle = new InputStreamHandle();
    handle.set(sourceStream);

    // write the resource extension to the database
    resourceMgr.writeServices(
        DictionaryManager.NAME, handle, metadata, new MethodParameters(MethodType.GET));

    System.out.println("(Strong Typed) Installed the resource extension on the server");
  }
  /**
   * Demonstrates use of BinaryDocumentManager. Use BinaryDocumentManager for insert or update of
   * binary documents.
   */
  public static void writeBinaryContent(DatabaseClient client) throws IOException {

    // create manager for Binary Documents
    BinaryDocumentManager docMgr = client.newBinaryDocumentManager();

    // create an identifier for the document
    String docId = "/binary/mlfavicon-1.png";

    // define mimetype
    String mimetype = "image/png";

    // write content to the database
    docMgr.write(
        docId,
        new FileHandle()
            .with(
                new File(
                    StreamReadWrite.class
                            .getProtectionDomain()
                            .getCodeSource()
                            .getLocation()
                            .getPath()
                        + File.separator
                        + "data"
                        + File.separator
                        + "mlfavicon.png"))
            .withMimetype(mimetype));

    System.out.println("writeBinaryContent() - Wrote " + docId + " content. \n");
  }
 @Override
 public void deleteAll(Transaction transaction) {
   QueryManager queryMgr = client.newQueryManager();
   DeleteQueryDefinition deleteQuery = queryMgr.newDeleteDefinition();
   deleteQuery.setCollections(entityClass.getName());
   queryMgr.delete(deleteQuery, transaction);
 }
  /** Demonstrates BytesHandle to buffer binary content */
  public static void readBinaryBuffer(DatabaseClient client) throws IOException {
    // create manager for Binary Documents
    BinaryDocumentManager docMgr = client.newBinaryDocumentManager();

    // create an identifier for the document
    String docId = "/binary/mlfavicon-2.png";

    InputStream docStream = docMgr.read(docId, new InputStreamHandle()).get();
    if (docStream == null) throw new IOException("Could not read document example");

    // create a handle to receive the document content
    BytesHandle readHandle = new BytesHandle();

    // read the document content
    docMgr.read(docId, readHandle);

    // to read part of the content
    // docMgr.read(docId, readHandle,9,10);

    // access the document content
    byte[] buf = readHandle.get();

    // ... do something with the document content ...

    System.out.println("\nRead " + docId + " with buffer having length: " + buf.length);
  }
 PojoRepositoryImpl(DatabaseClient client, Class<T> entityClass) {
   this.client = client;
   this.entityClass = entityClass;
   this.idClass = null;
   this.docMgr = client.newJSONDocumentManager();
   this.qb = new PojoQueryBuilderImpl<T>(entityClass);
 }
  @Test
  public void testPOJOSearchWithJacksonHandle() {
    PojoRepository<Artifact, Long> products = client.newPojoRepository(Artifact.class, Long.class);
    PojoPage<Artifact> p;
    this.loadSimplePojos(products);
    QueryManager queryMgr = client.newQueryManager();
    StringQueryDefinition qd = queryMgr.newStringDefinition();
    qd.setCriteria("cogs");
    JacksonHandle results = new JacksonHandle();
    p = products.search(qd, 1, results);
    products.setPageLength(11);
    assertEquals("total no of pages", 3, p.getTotalPages());
    //		System.out.println(p.getTotalPages()+results.get().toString());
    long pageNo = 1, count = 0;
    do {
      count = 0;
      p = products.search(qd, pageNo, results);

      while (p.iterator().hasNext()) {
        Artifact a = p.iterator().next();
        validateArtifact(a);
        count++;
        //				System.out.println(a.getId()+" "+a.getManufacturer().getName() +"  "+count);
      }
      assertEquals("Page size", count, p.size());
      pageNo = pageNo + p.getPageSize();

      assertEquals(
          "Page start from search handls vs page methods",
          results.get().get("start").asLong(),
          p.getStart());
      assertEquals(
          "Format in the search handle",
          "json",
          results.get().withArray("results").get(1).path("format").asText());
      assertTrue(
          "Uri in search handle contains Artifact",
          results.get().withArray("results").get(1).path("uri").asText().contains("Artifact"));
      //			System.out.println(results.get().toString());
    } while (!p.isLastPage() && pageNo < p.getTotalSize());
    //		assertTrue("search handle has metrics",results.get().has("metrics"));
    assertEquals("Search text is", "cogs", results.get().path("qtext").asText());
    assertEquals("Total from search handle", 110, results.get().get("total").asInt());
    assertEquals("page number after the loop", 10, p.getPageNumber());
    assertEquals("total no of pages", 10, p.getTotalPages());
  }
  @Test
  public void testPOJOSearchWithSearchHandle() {
    PojoRepository<Artifact, Long> products = client.newPojoRepository(Artifact.class, Long.class);
    PojoPage<Artifact> p;
    this.loadSimplePojos(products);
    QueryManager queryMgr = client.newQueryManager();
    StringQueryDefinition qd = queryMgr.newStringDefinition();
    qd.setCriteria("Acme");
    SearchHandle results = new SearchHandle();
    products.setPageLength(11);
    p = products.search(qd, 1, results);
    assertEquals("total no of pages", 5, p.getTotalPages());
    System.out.println(p.getTotalPages());
    long pageNo = 1, count = 0;
    do {
      count = 0;
      p = products.search(qd, pageNo, results);

      while (p.iterator().hasNext()) {
        Artifact a = p.iterator().next();
        validateArtifact(a);
        assertTrue("Artifact Id is even", a.getId() % 2 == 0);
        assertTrue("Company name contains Acme", a.getManufacturer().getName().contains("Acme"));
        count++;
        //				System.out.println(a.getId()+" "+a.getManufacturer().getName() +"  "+count);
      }
      assertEquals("Page size", count, p.size());
      pageNo = pageNo + p.getPageSize();
      MatchDocumentSummary[] mds = results.getMatchResults();
      assertEquals("Size of the results summary", 11, mds.length);
      for (MatchDocumentSummary md : mds) {
        assertTrue("every uri should contain the class name", md.getUri().contains("Artifact"));
      }
      String[] facetNames = results.getFacetNames();
      for (String fname : facetNames) {
        System.out.println(fname);
      }
      assertEquals("Total resulr from search handle ", 55, results.getTotalResults());
      //			assertTrue("Search Handle metric results ",results.getMetrics().getTotalTime()>0);
    } while (!p.isLastPage() && pageNo < p.getTotalSize());
    assertEquals("Page start check", 45, p.getStart());
    assertEquals("page number after the loop", 5, p.getPageNumber());
    assertEquals("total no of pages", 5, p.getTotalPages());
  }
  // Searching for Id as Number in JSON using range query
  @Test(expected = ClassCastException.class)
  public void testPOJOcombinedSearchforNumberWithStringHandle()
      throws JsonProcessingException, IOException {
    PojoRepository<Artifact, Long> products = client.newPojoRepository(Artifact.class, Long.class);
    PojoPage<Artifact> p;
    this.loadSimplePojos(products);

    QueryManager queryMgr = client.newQueryManager();
    String queryAsString =
        "{\"search\":{\"query\":{"
            + "\"range-constraint-query\":{\"constraint-name\":\"id\", \"value\":[5,10,15,20,25,30]}},"
            + "\"options\":{\"return-metrics\":false, \"constraint\":{\"name\":\"id\", \"range\":{\"type\": \"xs:long\",\"json-property\":\"id\"}}}"
            + "}}";
    PojoQueryDefinition qd =
        (PojoQueryDefinition)
            queryMgr.newRawCombinedQueryDefinition(
                new StringHandle(queryAsString).withFormat(Format.JSON));

    StringHandle results = new StringHandle();
    JacksonHandle jh = new JacksonHandle();
    p = products.search(qd, 1, jh);

    long pageNo = 1, count = 0;
    do {
      count = 0;
      p = products.search(qd, pageNo, results.withFormat(Format.JSON));

      while (p.iterator().hasNext()) {
        Artifact a = p.iterator().next();
        validateArtifact(a);
        count++;
      }
      assertEquals("Page total results", count, p.getTotalSize());
      pageNo = pageNo + p.getPageSize();
      System.out.println(results.get().toString());
    } while (!p.isLastPage() && pageNo < p.getTotalSize());
    assertFalse("String handle is not empty", results.get().isEmpty());
    assertTrue("String handle contains results", results.get().contains("results"));
    assertTrue("String handle contains format", results.get().contains("\"format\":\"json\""));
    ObjectMapper mapper = new ObjectMapper();
    JsonNode actNode = mapper.readTree(results.get()).get("total");
    assertEquals("Total search results resulted are ", 6, actNode.asInt());
  }
  @Test(expected = ClassCastException.class)
  public void testPOJOqbeSearchWithoutSearchHandle() {
    PojoRepository<Artifact, Long> products = client.newPojoRepository(Artifact.class, Long.class);
    PojoPage<Artifact> p;
    this.loadSimplePojos(products);
    QueryManager queryMgr = client.newQueryManager();
    String queryAsString =
        "{\"$query\":{"
            + "\"$and\":[{\"name\":{\"$word\":\"cogs\",\"$exact\": false}}]"
            + ",\"$not\":[{\"name\":{\"$word\":\"special\",\"$exact\": false}}]"
            + "}}";

    PojoQueryDefinition qd =
        (PojoQueryDefinition)
            queryMgr.newRawQueryByExampleDefinition(
                new StringHandle(queryAsString).withFormat(Format.JSON));
    qd.setCollections("odd");
    products.setPageLength(11);
    p = products.search(qd, 1);
    assertEquals("total no of pages", 4, p.getTotalPages());
    //		System.out.println(p.getTotalPages());
    long pageNo = 1, count = 0;
    do {
      count = 0;

      p = products.search(qd, pageNo);

      while (p.iterator().hasNext()) {
        Artifact a = p.iterator().next();
        validateArtifact(a);
        assertFalse("Verifying document with special is not there", a.getId() % 5 == 0);
        assertTrue("Artifact Id is odd", a.getId() % 2 != 0);
        assertTrue(
            "Company name contains widgets", a.getManufacturer().getName().contains("Widgets"));
        count++;
        //				System.out.println(a.getId()+" "+a.getManufacturer().getName() +"  "+count);
      }
      assertEquals("Page size", count, p.size());
      pageNo = pageNo + p.getPageSize();
    } while (!p.isLastPage() && pageNo < p.getTotalSize());
    assertEquals("page number after the loop", 4, p.getPageNumber());
    assertEquals("total no of pages", 4, p.getTotalPages());
  }
  /**
   * Demonstrates how to write content to a document using an OutputStream. You provide the content
   * during execution of the write operation instead of when starting the write operation.
   */
  public static void readWriteBinaryStream(DatabaseClient client) throws IOException {

    BinaryDocumentManager docMgr = client.newBinaryDocumentManager();

    final int MAX_BUF = 8192;
    final String FILENAME = "mlfavicon.png";
    // String docIdToRead = "/binary/mlfavicon.png";
    String docIdToRead = "data" + File.separator + FILENAME;
    String docIdToWrite = "/binary/mlfavicon-2.png";

    // create an anonymous class with a callback method
    OutputStreamSender sender =
        new OutputStreamSender() {
          // the callback receives the output stream
          public void write(OutputStream out) throws IOException {

            // acquire the content from the database
            /* InputStream docStream =
            		docMgr.read(docIdToRead, new InputStreamHandle()).get();
            		if (docStream == null)
            			throw new IOException("Could not read document example");
            */

            // acquire the content from the file system
            InputStream docStream = Util.openStream(docIdToRead);
            if (docStream == null) throw new IOException("Could not read document example");

            // copy content to the output stream
            byte[] buf = new byte[MAX_BUF];
            int byteCount = 0;
            while ((byteCount = docStream.read(buf)) != -1) {
              out.write(buf, 0, byteCount);
            }
          }
        };

    // create a handle for writing the content
    OutputStreamHandle handle = new OutputStreamHandle(sender);

    // write the document content
    docMgr.write(docIdToWrite, handle);

    System.out.println(
        "readWriteBinaryStream() - \n"
            + "Read "
            + docIdToRead
            + " content. \n"
            + "Wrote "
            + docIdToWrite
            + " content. \n");
  }
  // Searching for Id as Number in JSON using string should not return any results
  @Test
  public void testPOJOSearchWithStringHandle() throws JsonProcessingException, IOException {
    PojoRepository<Artifact, Long> products = client.newPojoRepository(Artifact.class, Long.class);
    PojoPage<Artifact> p;
    this.loadSimplePojos(products);
    QueryManager queryMgr = client.newQueryManager();
    StringQueryDefinition qd = queryMgr.newStringDefinition();
    qd.setCriteria("5");
    StringHandle results = new StringHandle();
    JacksonHandle jh = new JacksonHandle();
    p = products.search(qd, 1, jh);

    long pageNo = 1, count = 0;
    do {
      count = 0;
      p = products.search(qd, pageNo, results.withFormat(Format.JSON));

      while (p.iterator().hasNext()) {
        Artifact a = p.iterator().next();
        validateArtifact(a);
        count++;
        //				System.out.println(a.getId()+" "+a.getManufacturer().getName() +"  "+count);
      }
      assertEquals("Page total results", 0, p.getTotalSize());
      pageNo = pageNo + p.getPageSize();
      //				System.out.println(results.get().toString());
    } while (!p.isLastPage() && pageNo < p.getTotalSize());
    assertFalse("String handle is not empty", results.get().isEmpty());
    assertTrue("String handle contains results", results.get().contains("results"));
    assertFalse("String handle contains format", results.get().contains("\"format\":\"json\""));

    ObjectMapper mapper = new ObjectMapper();
    JsonNode actNode = mapper.readTree(results.get()).get("total");
    //		System.out.println(expNode.equals(actNode)+"\n"+
    // expNode.toString()+"\n"+actNode.toString());

    assertEquals("Total search results resulted are ", actNode.asInt(), 0);
  }
  @Bean
  @Scope("singleton")
  public DatabaseClient databaseClient() {
    final String host = Play.application().configuration().getString("ml.host");
    final int port = Play.application().configuration().getInt("ml.port");
    final String user = "******";
    final String password = "******";

    DatabaseClient db =
        DatabaseClientFactory.newClient(host, port, user, password, Authentication.DIGEST);

    String options =
        "<search:options "
            + "xmlns:search='http://marklogic.com/appservices/search'>"
            + "<search:return-results>true</search:return-results>"
            + "<search:transform-results apply='raw' />"
            + "</search:options>";

    QueryOptionsManager optionsMgr = db.newServerConfigManager().newQueryOptionsManager();
    optionsMgr.writeOptions("default", new StringHandle(options));

    return db;
  }
  public void loadXMLDocuments()
      throws IOException, ParserConfigurationException, SAXException, TransformerException {
    int count = 1;
    XMLDocumentManager docMgr = client.newXMLDocumentManager();
    DocumentWriteSet writeset = docMgr.newWriteSet();
    for (int i = 0; i < 102; i++) {

      writeset.add(
          DIRECTORY + "foo" + i + ".xml",
          new DOMHandle(getDocumentContent("This is so foo with a bar " + i)));

      if (count % BATCH_SIZE == 0) {
        docMgr.write(writeset);
        writeset = docMgr.newWriteSet();
      }
      count++;
    }
    if (count % BATCH_SIZE > 0) {
      docMgr.write(writeset);
    }
  }
  public void loadJSONDocuments() throws JsonProcessingException, IOException {
    int count = 1;
    JSONDocumentManager docMgr = client.newJSONDocumentManager();
    DocumentWriteSet writeset = docMgr.newWriteSet();

    HashMap<String, String> map = new HashMap<String, String>();

    for (int i = 0; i < 102; i++) {
      JsonNode jn = new ObjectMapper().readTree("{\"animal\":\"dog" + i + "\", \"says\":\"woof\"}");
      JacksonHandle jh = new JacksonHandle();
      jh.set(jn);
      writeset.add(DIRECTORY + "dog" + i + ".json", jh);
      map.put(DIRECTORY + "dog" + i + ".json", jn.toString());
      if (count % BATCH_SIZE == 0) {
        docMgr.write(writeset);
        writeset = docMgr.newWriteSet();
      }
      count++;
      //	      System.out.println(jn.toString());
    }
    if (count % BATCH_SIZE > 0) {
      docMgr.write(writeset);
    }
  }
 @After
 public void tearDown() throws Exception {
   // release client
   client.release();
 }
  // This test is to verify RAW JSON structured query
  @Test
  public void testBulkSearchRawJSONStrucQD() throws Exception {
    //		setAutomaticDirectoryCreation(dbName,"automatic");
    setMaintainLastModified(dbName, true);
    this.loadJSONDocuments();
    this.loadXMLDocuments();
    GenericDocumentManager docMgr = client.newDocumentManager();
    QueryManager queryMgr = client.newQueryManager();
    JacksonHandle jh = new JacksonHandle();
    ObjectMapper mapper = new ObjectMapper();
    //	constructing JSON representation of Raw JSON Structured Query

    ObjectNode txtNode = mapper.createObjectNode();
    txtNode.putArray("text").add("woof");
    ObjectNode termQNode = mapper.createObjectNode();
    termQNode.set("term-query", txtNode);
    ObjectNode queriesArrayNode = mapper.createObjectNode();
    queriesArrayNode.putArray("queries").add(termQNode);

    ObjectNode txtNode2 = mapper.createObjectNode();
    txtNode2.putArray("text").add("bar");
    ObjectNode termQNode2 = mapper.createObjectNode();
    termQNode2.set("term-query", txtNode2);
    queriesArrayNode.withArray("queries").add(termQNode2);

    ObjectNode orQueryNode = mapper.createObjectNode();
    orQueryNode.set("or-query", queriesArrayNode);

    ObjectNode queryArrayNode = mapper.createObjectNode();
    queryArrayNode.putArray("queries").add(orQueryNode);
    ObjectNode mainNode = mapper.createObjectNode();
    mainNode.set("query", queryArrayNode);
    jh.set(mainNode);
    RawStructuredQueryDefinition qd = queryMgr.newRawStructuredQueryDefinition(jh);
    System.out.println(jh.get().toString());
    docMgr.setNonDocumentFormat(Format.JSON);
    JacksonHandle results = new JacksonHandle();
    DocumentPage page = docMgr.search(qd, 1, results);
    DocumentMetadataHandle mh = new DocumentMetadataHandle();

    int count = 1;
    while (count < 4) {
      page = docMgr.search(qd, count, results);

      while (page.hasNext()) {
        DocumentRecord rec = page.next();
        if (rec.getMimetype().contains("xml")) {
          validateRecord(rec, Format.XML);
        } else {
          validateRecord(rec, Format.JSON);
        }
        docMgr.readMetadata(rec.getUri(), mh);
        assertTrue("Records has permissions? ", mh.getPermissions().containsKey("flexrep-eval"));
        assertFalse("Record has collections ?", mh.getCollections().isEmpty());
      }

      count++;
    }
    System.out.println(results.get().toString());
    assertEquals(
        "Total search results before transaction rollback are ",
        "204",
        results.get().get("total").asText());
  }
  /* Searching for boolean and string in XML element using value query.
   * Purpose: To validate QueryBuilder's new value methods (in 8.0) in XML document using an element.
   *
   * Load a file that has a boolean value in a XML attribute and use query def to search on that boolean value
   *
   * Methods used : value(StructuredQueryBuilder.TextIndex index, boolean)
   *                value(StructuredQueryBuilder.TextIndex index, String)
   */
  @Test
  public void testQueryBuilderValueWithBooleanAndString()
      throws XpathException, SAXException, IOException {

    String docId[] = {"play-persons.xml"};

    TextDocumentManager docMgr = client.newTextDocumentManager();
    QueryManager queryMgr = client.newQueryManager();
    DocumentWriteSet writeset = docMgr.newWriteSet();

    // Put meta-data

    DocumentMetadataHandle metadataHandle = new DocumentMetadataHandle();
    metadataHandle.getCollections().addAll("my-collection1", "my-collection2");
    metadataHandle.getPermissions().add("app-user", Capability.UPDATE, Capability.READ);
    metadataHandle.getProperties().put("reviewed", true);
    metadataHandle.getProperties().put("myString", "foo");
    metadataHandle.getProperties().put("myInteger", 10);
    metadataHandle.getProperties().put("myDecimal", 34.56678);
    metadataHandle.getProperties().put("myCalendar", Calendar.getInstance().get(Calendar.YEAR));
    metadataHandle.setQuality(23);

    writeset.addDefault(metadataHandle);

    // Create a new document using StringHandle
    StringBuffer strBuf = new StringBuffer();

    strBuf.append("<PLAY>");
    strBuf.append("<TITLE>All's Well That Ends Well</TITLE>");
    strBuf.append("<PERSONAE>");
    strBuf.append("<TITLE>Dramatis Personae</TITLE>");

    strBuf.append("<PGROUP>");
    strBuf.append("<subgroup>true</subgroup>");

    strBuf.append("<PERSONA>KING OF FRANCE</PERSONA>");
    strBuf.append("<PERSONA>DUKE OF FLORENCE</PERSONA>");
    strBuf.append("<PERSONA>BERTRAM, Count of Rousillon.</PERSONA>");
    strBuf.append("<PERSONA>LAFEU, an old lord.</PERSONA>");
    strBuf.append("</PGROUP>");

    strBuf.append("<PGROUP>");
    strBuf.append("<subgroup>false</subgroup>");

    strBuf.append("<PERSONA>PAROLLES, a follower of Bertram.</PERSONA>");
    strBuf.append("<PERSONA>A Page. </PERSONA>");
    strBuf.append("</PGROUP>");

    strBuf.append("<PGROUP>");
    strBuf.append("<subgroup>false</subgroup>");
    strBuf.append("<PERSONA>COUNTESS OF ROUSILLON, mother to Bertram. </PERSONA>");
    strBuf.append("<PERSONA>HELENA, a gentlewoman protected by the Countess.</PERSONA>");
    strBuf.append("<PERSONA>An old Widow of Florence. </PERSONA>");
    strBuf.append("<PERSONA>DIANA, daughter to the Widow.</PERSONA>");
    strBuf.append("</PGROUP>");

    strBuf.append("<PGROUP>");
    strBuf.append("<subgroup>false</subgroup>");
    strBuf.append("<PERSONA>VIOLENTA</PERSONA>");
    strBuf.append("<PERSONA>MARIANA</PERSONA>");
    strBuf.append("<GRPDESCR>neighbours and friends to the Widow.</GRPDESCR>");
    strBuf.append("</PGROUP>");

    strBuf.append("<PERSONA>Lords, Officers, Soldiers, &amp;c., French and Florentine.</PERSONA>");
    strBuf.append("</PERSONAE>");
    strBuf.append("</PLAY>");

    writeset.add("/1/" + docId[0], new StringHandle().with(strBuf.toString()));
    docMgr.write(writeset);

    docMgr.write(writeset);

    // Search for the range with attribute value true in rangeRelativeBucketConstraintOpt.xml
    // document.
    StructuredQueryBuilder qb = new StructuredQueryBuilder();

    // Build an object that represents StructuredQueryBuilder.ElementAttribute for use in values
    // method
    // that is of type StructuredQueryBuilder.TextIndex

    QueryDefinition qd = qb.value(qb.element("subgroup"), false);

    // Create handle for the result
    StringHandle resultsHandle = new StringHandle().withFormat(Format.XML);
    queryMgr.search(qd, resultsHandle);

    // Get the result
    String resultDoc = resultsHandle.get();

    System.out.println(resultDoc);
    // Verify that search response has found 1 element attribute
    assertXpathEvaluatesTo(
        "fn:doc(\"/1/play-persons.xml\")",
        "string(//*[local-name()='response']//*[local-name()='result']//@*[local-name()='path'])",
        resultDoc);
    assertXpathEvaluatesTo(
        "3", "count(//*[local-name()='response']//*[local-name()='match'])", resultDoc);

    // Search for the following royal (XML ELEMENT) in all-well.xml document.
    StructuredQueryBuilder qbStr = new StructuredQueryBuilder();
    QueryDefinition qdStr =
        qbStr.value(
            qbStr.element("PERSONA"),
            "KING OF FRANCE",
            "DUKE OF FLORENCE",
            "BERTRAM, Count of Rousillon.",
            "LAFEU, an old lord.");

    // Create handle for the result
    StringHandle resultsHandleStr = new StringHandle().withFormat(Format.XML);
    queryMgr.search(qdStr, resultsHandleStr);

    // Get the result
    String resultDocStr = resultsHandleStr.get();

    System.out.println(resultDocStr);
    // Verify that search response has found 4 PERSONA elements under /PLAY/PERSONAE
    assertXpathEvaluatesTo(
        "fn:doc(\"/1/play-persons.xml\")",
        "string(//*[local-name()='response']//*[local-name()='result']//@*[local-name()='path'])",
        resultDocStr);
    assertXpathEvaluatesTo(
        "4", "count(//*[local-name()='response']//*[local-name()='match'])", resultDocStr);
  }