/**
   * Add an new empty feed::dasextension element with only a completed management element to the
   * given Feed. Sets the responseTime value to now. Note: A proper sites::site element must be
   * added to the new feed::dasextension element for this new feed::dasextension element to be
   * valid.
   *
   * @param feed - mandatory
   * @return
   */
  private Feed addEmptyDasExtension(Feed feed) {

    // check to make sure there's a dasextension
    QName dasextensionQname = new QName(this.dasextensionNamespace, "dasextension");
    ExtensibleElement dasExt = feed.getExtension(dasextensionQname);
    if (NullChecker.isEmpty(dasExt)) {

      dasExt = feed.addExtension(dasextensionQname);

      // add the dasextension::management element
      QName managementQname = new QName(this.dasextensionNamespace, "management");
      ExtensibleElement management = dasExt.getExtension(managementQname);
      if (NullChecker.isEmpty(management)) {
        management = dasExt.addExtension(managementQname);
      }

      QName responseTimeQname = new QName(this.dasextensionNamespace, "responseTime");
      ExtensibleElement responseTime = management.getExtension(responseTimeQname);
      if (NullChecker.isEmpty(responseTime)) {
        responseTime = management.addExtension(responseTimeQname);
      }

      // set/reset the response time to now
      XMLGregorianCalendar xmlGregCalResponseTime =
          GregorianDateUtil.getGregorianCalendarByDate(new Date());
      responseTime.setText(xmlGregCalResponseTime.toString()); // TODO: Verify date format
    }
    return feed;
  }
  @Test
  @RunAsClient
  public void testUpdateAssetFromAtomWithStateNotExist(@ArquillianResource URL baseURL)
      throws Exception {
    URL url = new URL(baseURL + "rest/packages/restPackage1/assets/model1");
    HttpURLConnection connection = (HttpURLConnection) url.openConnection();
    connection.setRequestProperty(
        "Authorization", "Basic " + new Base64().encodeToString(("admin:admin".getBytes())));
    connection.setRequestMethod("GET");
    connection.setRequestProperty("Accept", MediaType.APPLICATION_ATOM_XML);
    connection.connect();
    assertEquals(200, connection.getResponseCode());
    assertEquals(MediaType.APPLICATION_ATOM_XML, connection.getContentType());
    InputStream in = connection.getInputStream();
    assertNotNull(in);
    Document<Entry> doc = abdera.getParser().parse(in);
    Entry entry = doc.getRoot();

    // Update state
    ExtensibleElement metadataExtension = entry.getExtension(Translator.METADATA);
    ExtensibleElement stateExtension = metadataExtension.getExtension(Translator.STATE);
    stateExtension.<Element>getExtension(Translator.VALUE).setText("NonExistState");

    connection = (HttpURLConnection) url.openConnection();
    connection.setRequestProperty(
        "Authorization", "Basic " + new Base64().encodeToString(("admin:admin".getBytes())));
    connection.setRequestMethod("PUT");
    connection.setRequestProperty("Content-type", MediaType.APPLICATION_ATOM_XML);
    connection.setDoOutput(true);
    entry.writeTo(connection.getOutputStream());
    assertEquals(500, connection.getResponseCode());
    connection.disconnect();
  }
  /**
   * Find the current dasextension::query::sites element or create a new one in the proper place in
   * the given dasextension element.
   *
   * @param dasExt - mandatory - must be a valid dasextension Element
   * @return
   */
  public ExtensibleElement getSites(ExtensibleElement dasExt) {

    // get reference to the dasextension::query element in feed
    ExtensibleElement query = this.getQuery(dasExt);

    // get reference to the dasextension::query::sites element in feed
    QName sitesQname = new QName(this.dasextensionNamespace, "sites");
    ExtensibleElement sites = query.getExtension(sitesQname);
    if (NullChecker.isEmpty(sites)) {
      ExtensibleElement queryFirstChild = query.getFirstChild();
      if (NullChecker.isEmpty(queryFirstChild)) {
        // no children in query, so merely add sites element
        sites = query.addExtension(sitesQname);
      } else {
        QName fCQname = queryFirstChild.getQName();
        if ("parameters".equals(fCQname.getLocalPart())) {
          ExtensibleElement querySecondChild = query.getNextSibling();
          if (NullChecker.isEmpty(querySecondChild)) {
            // no second child in query, so add sites after parameters
            sites = query.addExtension(sitesQname);
          } else {
            // add sites after parameters, and before the second child
            QName sCQname = querySecondChild.getQName();
            sites = query.addExtension(sitesQname, sCQname);
          }
        } else {
          // another element besides parameters is first child,
          //  so add sites before this
          sites = dasExt.addExtension(sitesQname, fCQname);
        }
      }
    }
    return sites;
  }
  /**
   * Find the current dasextension::query element or create a new one in the proper place in the
   * given dasextension element.
   *
   * @param dasExt - mandatory - must be a valid dasextension Element
   * @return
   */
  private ExtensibleElement getQuery(ExtensibleElement dasExt) {

    QName queryQname = new QName(this.dasextensionNamespace, "query");
    // attempt to get query element
    ExtensibleElement query = dasExt.getExtension(queryQname);
    if (NullChecker.isEmpty(query)) {
      // there is no query element, so create one in the proper place
      ExtensibleElement firstChild = dasExt.getFirstChild();
      if (NullChecker.isEmpty(firstChild)) {
        // no children, so merely add query
        query = dasExt.addExtension(queryQname);
      } else {
        QName fCQname = firstChild.getQName();
        if ("path".equals(fCQname.getLocalPart())) {
          // path is the firstChild, so get the second child
          ExtensibleElement secondChild = firstChild.getNextSibling();
          if (NullChecker.isEmpty(secondChild)) {
            // no second child, so add query after path
            query = dasExt.addExtension(queryQname);
          } else {
            QName sCQname = secondChild.getQName();
            // have a second child, so add query after
            // path element and before second child
            query = dasExt.addExtension(queryQname, sCQname);
          }
        } else {
          // add query before the first child element
          query = dasExt.addExtension(queryQname, fCQname);
        }
      }
    }
    return query;
  }
  /**
   * Returns true if the the given dasExt contains a feed::dasextension::query::parameters element,
   * else false.
   *
   * @param dasExt - mandatory - must be a valid dasextension Element
   * @return
   */
  private boolean queryParametersExists(ExtensibleElement dasExt) {

    boolean queryParametersExists = false;

    if (NullChecker.isNotEmpty(dasExt)) {
      QName queryQname = new QName(this.dasextensionNamespace, "query");
      ExtensibleElement query = dasExt.getExtension(queryQname);
      if (NullChecker.isNotEmpty(query)) {
        QName parametersQname = new QName(this.dasextensionNamespace, "parameters");
        ExtensibleElement parameters = query.getExtension(parametersQname);
        if (NullChecker.isNotEmpty(parameters)) {
          queryParametersExists = true;
        }
      }
    }
    return queryParametersExists;
  }
  /**
   * Returns true if the the given dasExt contains a feed::dasextension::path::parameters element,
   * else false.
   *
   * @param dasExt - mandatory - must be a valid dasextension Element
   * @return
   */
  private boolean pathParametersExists(ExtensibleElement dasExt) {

    boolean pathParametersExists = false;

    if (NullChecker.isNotEmpty(dasExt)) {
      QName pathQname = new QName(this.dasextensionNamespace, "path");
      ExtensibleElement path = dasExt.getExtension(pathQname);
      if (NullChecker.isNotEmpty(path)) {
        QName parametersQname = new QName(this.dasextensionNamespace, "parameters");
        ExtensibleElement parameters = path.getExtension(parametersQname);
        if (NullChecker.isNotEmpty(parameters)) {
          pathParametersExists = true;
        }
      }
    }
    return pathParametersExists;
  }
  @Test
  @RunAsClient
  public void testGetAssetAsAtom(@ArquillianResource URL baseURL) throws Exception {
    URL url = new URL(baseURL, "rest/packages/restPackage1/assets/model1");
    HttpURLConnection connection = (HttpURLConnection) url.openConnection();
    connection.setRequestProperty(
        "Authorization", "Basic " + new Base64().encodeToString(("admin:admin".getBytes())));
    connection.setRequestMethod("GET");
    connection.setRequestProperty("Accept", MediaType.APPLICATION_ATOM_XML);
    connection.connect();
    assertEquals(200, connection.getResponseCode());
    assertEquals(MediaType.APPLICATION_ATOM_XML, connection.getContentType());
    // System.out.println(getContent(connection));

    InputStream in = connection.getInputStream();
    assertNotNull(in);
    Document<Entry> doc = abdera.getParser().parse(in);
    Entry entry = doc.getRoot();
    assertEquals(
        baseURL.getPath() + "rest/packages/restPackage1/assets/model1",
        entry.getBaseUri().getPath());
    assertEquals("model1", entry.getTitle());
    assertNotNull(entry.getPublished());
    assertNotNull(entry.getAuthor().getName());
    assertEquals("desc for model1", entry.getSummary());
    // assertEquals(MediaType.APPLICATION_OCTET_STREAM_TYPE.getType(),
    // entry.getContentMimeType().getPrimaryType());
    assertEquals(
        baseURL.getPath() + "rest/packages/restPackage1/assets/model1/binary",
        entry.getContentSrc().getPath());

    ExtensibleElement metadataExtension = entry.getExtension(Translator.METADATA);
    ExtensibleElement archivedExtension = metadataExtension.getExtension(Translator.ARCHIVED);
    assertEquals("false", archivedExtension.getSimpleExtension(Translator.VALUE));
    ExtensibleElement stateExtension = metadataExtension.getExtension(Translator.STATE);
    assertEquals("Draft", stateExtension.getSimpleExtension(Translator.VALUE));
    ExtensibleElement formatExtension = metadataExtension.getExtension(Translator.FORMAT);
    assertEquals("model.drl", formatExtension.getSimpleExtension(Translator.VALUE));
    ExtensibleElement uuidExtension = metadataExtension.getExtension(Translator.UUID);
    assertNotNull(uuidExtension.getSimpleExtension(Translator.VALUE));
    ExtensibleElement categoryExtension = metadataExtension.getExtension(Translator.CATEGORIES);
    assertEquals(
        "AssetPackageResourceTestCategory", categoryExtension.getSimpleExtension(Translator.VALUE));
  }
  /**
   * Find the current dasextension::query::errors element or create a new one in the proper place in
   * the given dasextension element.
   *
   * @param dasExt - mandatory - must be a valid dasextension Element
   * @return
   */
  public ExtensibleElement getErrors(ExtensibleElement dasExt) {

    // get reference to the dasextension::query element in feed
    ExtensibleElement query = this.getQuery(dasExt);

    // get reference to the dasextension::query::errors element in feed
    QName errorsQname = new QName(this.dasextensionNamespace, "errors");
    ExtensibleElement errors = query.getExtension(errorsQname);
    if (NullChecker.isEmpty(errors)) {
      List<Element> queryChildren = query.getElements();
      if (NullChecker.isEmpty(queryChildren)) {
        // no children in query, so merely add errors element
        errors = query.addExtension(errorsQname);
      } else {
        // add errors after the last child
        errors = query.addExtension(errorsQname);
      }
    }
    return errors;
  }
  @Test
  @RunAsClient
  public void testUpdateAssetFromAtom(@ArquillianResource URL baseURL) throws Exception {
    URL url = new URL(baseURL + "rest/packages/restPackage1/assets/model1");
    HttpURLConnection connection = (HttpURLConnection) url.openConnection();
    connection.setRequestProperty(
        "Authorization", "Basic " + new Base64().encodeToString(("admin:admin".getBytes())));
    connection.setRequestMethod("GET");
    connection.setRequestProperty("Accept", MediaType.APPLICATION_ATOM_XML);
    connection.connect();
    assertEquals(200, connection.getResponseCode());
    assertEquals(MediaType.APPLICATION_ATOM_XML, connection.getContentType());
    // System.out.println(GetContent(connection));

    InputStream in = connection.getInputStream();
    assertNotNull(in);
    Document<Entry> doc = abdera.getParser().parse(in);
    Entry entry = doc.getRoot();
    assertEquals(
        baseURL.getPath() + "rest/packages/restPackage1/assets/model1",
        entry.getBaseUri().getPath());
    assertEquals("model1", entry.getTitle());
    assertNotNull(entry.getPublished());
    assertNotNull(entry.getAuthor().getName());
    assertEquals("desc for model1", entry.getSummary());
    // assertEquals(MediaType.APPLICATION_OCTET_STREAM_TYPE.getType(),
    // entry.getContentMimeType().getPrimaryType());
    assertEquals(
        baseURL.getPath() + "rest/packages/restPackage1/assets/model1/binary",
        entry.getContentSrc().getPath());

    ExtensibleElement metadataExtension = entry.getExtension(Translator.METADATA);
    ExtensibleElement archivedExtension = metadataExtension.getExtension(Translator.ARCHIVED);
    assertEquals("false", archivedExtension.getSimpleExtension(Translator.VALUE));
    ExtensibleElement stateExtension = metadataExtension.getExtension(Translator.STATE);
    assertEquals("Draft", stateExtension.getSimpleExtension(Translator.VALUE));
    ExtensibleElement formatExtension = metadataExtension.getExtension(Translator.FORMAT);
    assertEquals("model.drl", formatExtension.getSimpleExtension(Translator.VALUE));
    ExtensibleElement uuidExtension = metadataExtension.getExtension(Translator.UUID);
    assertNotNull(uuidExtension.getSimpleExtension(Translator.VALUE));
    ExtensibleElement categoryExtension = metadataExtension.getExtension(Translator.CATEGORIES);
    assertEquals(
        "AssetPackageResourceTestCategory", categoryExtension.getSimpleExtension(Translator.VALUE));
    connection.disconnect();

    // Update category. Add a new category tag
    categoryExtension.addSimpleExtension(Translator.VALUE, "AssetPackageResourceTestCategory2");
    // Update state
    stateExtension.<Element>getExtension(Translator.VALUE).setText("Dev");
    // Update format
    formatExtension.<Element>getExtension(Translator.VALUE).setText("anotherformat");

    connection = (HttpURLConnection) url.openConnection();
    connection.setRequestProperty(
        "Authorization", "Basic " + new Base64().encodeToString(("admin:admin".getBytes())));
    connection.setRequestMethod("PUT");
    connection.setRequestProperty("Content-type", MediaType.APPLICATION_ATOM_XML);
    connection.setDoOutput(true);
    entry.writeTo(connection.getOutputStream());
    assertEquals(204, connection.getResponseCode());
    connection.disconnect();

    // Verify again
    connection = (HttpURLConnection) url.openConnection();
    connection.setRequestProperty(
        "Authorization", "Basic " + new Base64().encodeToString(("admin:admin".getBytes())));
    connection.setRequestMethod("GET");
    connection.setRequestProperty("Accept", MediaType.APPLICATION_ATOM_XML);
    connection.connect();
    assertEquals(200, connection.getResponseCode());
    // System.out.println(GetContent(connection));

    in = connection.getInputStream();
    assertNotNull(in);
    doc = abdera.getParser().parse(in);
    entry = doc.getRoot();

    metadataExtension = entry.getExtension(Translator.METADATA);
    archivedExtension = metadataExtension.getExtension(Translator.ARCHIVED);
    assertEquals("false", archivedExtension.getSimpleExtension(Translator.VALUE));
    stateExtension = metadataExtension.getExtension(Translator.STATE);
    assertEquals("Dev", stateExtension.getSimpleExtension(Translator.VALUE));
    formatExtension = metadataExtension.getExtension(Translator.FORMAT);
    assertEquals("anotherformat", formatExtension.getSimpleExtension(Translator.VALUE));
    categoryExtension = metadataExtension.getExtension(Translator.CATEGORIES);
    List<Element> categoryValues = categoryExtension.getExtensions(Translator.VALUE);
    assertTrue(categoryValues.size() == 2);
    boolean foundCategory1 = false;
    boolean foundCategory2 = false;
    for (Element cat : categoryValues) {
      String catgoryValue = cat.getText();
      if ("AssetPackageResourceTestCategory".equals(catgoryValue)) {
        foundCategory1 = true;
      }
      if ("AssetPackageResourceTestCategory2".equals(catgoryValue)) {
        foundCategory2 = true;
      }
    }
    assertTrue(foundCategory1);
    assertTrue(foundCategory2);
  }