@Test
  public void test2() throws Exception {
    ObjectViews views = this.unmarshal("com/axelor/meta/WSTest.xml", ObjectViews.class);

    MetaStore.resister(views);

    Action action = MetaStore.getAction("export.sale.order");
    Map<String, Object> context = Maps.newHashMap();

    context.put("name", "SO001");
    context.put("orderDate", new LocalDate());
    context.put("customer", ImmutableMap.of("name", "John Smith"));

    List<Object> items = Lists.newArrayList();
    context.put("items", items);

    items.add(
        ImmutableMap.of("product", ImmutableMap.of("name", "PC1"), "price", 250, "quantity", 1));
    items.add(
        ImmutableMap.of("product", ImmutableMap.of("name", "PC2"), "price", 550, "quantity", 1));
    items.add(
        ImmutableMap.of("product", ImmutableMap.of("name", "Laptop"), "price", 690, "quantity", 1));

    ActionHandler handler = createHandler("export.sale.order", context);
    action.evaluate(handler);
  }
  private void initializeCursors(final ManagedLedgerCallback<Void> callback) {
    log.debug("[{}] initializing cursors", name);
    store.getConsumers(
        name,
        new MetaStoreCallback<List<Pair<String, Position>>>() {
          public void operationComplete(List<Pair<String, Position>> result, Version v) {
            // Load existing cursors
            try {
              for (Pair<String, Position> pair : result) {
                log.debug("[{}] Loading cursor {}", name, pair);
                cursors.add(new ManagedCursorImpl(ManagedLedgerImpl.this, pair.first, pair.second));
              }
            } catch (InterruptedException e) {
              Thread.currentThread().interrupt();
              callback.operationFailed(new ManagedLedgerException(e));
              return;
            } catch (ManagedLedgerException e) {
              callback.operationFailed(e);
              return;
            }

            // Calculate total entries and size
            for (LedgerStat ls : ledgers.values()) {
              numberOfEntries.addAndGet(ls.getEntriesCount());
              totalSize.addAndGet(ls.getSize());
            }
            callback.operationComplete(null);
          }

          public void operationFailed(MetaStoreException e) {
            callback.operationFailed(new ManagedLedgerException(e));
          }
        });
  }
  @Test
  public void testGroup() {
    Action action = MetaStore.getAction("action.group.test");
    Map<String, Object> context = Maps.newHashMap();

    context.put("id", 1);
    context.put("firstName", "John");
    context.put("lastName", "Smith");

    ActionHandler handler = createHandler(action, context);
    Object value = action.evaluate(handler);

    Assert.assertNotNull(value);
    Assert.assertTrue(value instanceof List);
    Assert.assertFalse(((List<?>) value).isEmpty());
    Assert.assertNotNull(((List<?>) value).get(0));
    Assert.assertFalse(value.toString().contains("pending"));

    handler.getContext().update("firstName", "J");
    handler.getContext().update("email", "*****@*****.**");

    value = action.evaluate(handler);

    Assert.assertNotNull(value);
    Assert.assertTrue(value instanceof List);
    Assert.assertFalse(((List<?>) value).isEmpty());
    Assert.assertNotNull(((List<?>) value).get(0));
    Assert.assertTrue(value.toString().contains("pending"));
  }
  synchronized void initialize(final ManagedLedgerCallback<Void> callback) {
    log.info("Opening managed ledger {}", name);

    // Fetch the list of existing ledgers in the managed ledger
    store.getLedgerIds(
        name,
        new MetaStoreCallback<List<LedgerStat>>() {
          public void operationComplete(List<LedgerStat> result, Version version) {
            ledgersVersion = version;
            for (LedgerStat ls : result) {
              ledgers.put(ls.getLedgerId(), ls);
            }

            // Last ledger stat may be zeroed, we must update it
            if (ledgers.size() > 0) {
              final long id = ledgers.lastKey();
              OpenCallback opencb =
                  new OpenCallback() {
                    public void openComplete(int rc, LedgerHandle lh, Object ctx) {
                      if (rc == BKException.Code.OK) {
                        ledgers.put(
                            id, new LedgerStat(id, lh.getLastAddConfirmed() + 1, lh.getLength()));
                        lh.asyncClose(
                            new AsyncCallback.CloseCallback() {
                              public void closeComplete(int rc, LedgerHandle lh, Object ctx) {
                                if (rc == BKException.Code.OK) {
                                  initializeBookKeeper(callback);
                                } else {
                                  callback.operationFailed(
                                      new ManagedLedgerException(BKException.create(rc)));
                                }
                              }
                            },
                            null);
                      } else if (rc == BKException.Code.NoSuchLedgerExistsException) {
                        log.warn("[{}] Ledger not found: {}", name, ledgers.lastKey());
                        initializeBookKeeper(callback);
                      } else {
                        callback.operationFailed(
                            new ManagedLedgerException(BKException.create(rc)));
                        return;
                      }
                    }
                  };
              bookKeeper.asyncOpenLedger(
                  id, config.getDigestType(), config.getPassword(), opencb, null);
            } else {
              initializeBookKeeper(callback);
            }
          }

          public void operationFailed(MetaStoreException e) {
            callback.operationFailed(new ManagedLedgerException(e));
          }
        });
  }
  @Test
  public void test1() throws Exception {
    ObjectViews views = this.unmarshal("com/axelor/meta/WSTest.xml", ObjectViews.class);
    List<Action> actions = views.getActions();

    Assert.assertNotNull(actions);
    Assert.assertEquals(4, actions.size());

    MetaStore.resister(views);

    Action action = MetaStore.getAction("data.import.1");
    Map<String, Object> context = Maps.newHashMap();

    DateTime dt = new DateTime();
    dt = dt.plus(Period.days(20));

    context.put("dt", dt);

    ActionHandler handler = createHandler("data.import.1", context);
    action.evaluate(handler);
  }
  @Before
  public void setUp() {
    try {
      views = this.unmarshal("com/axelor/meta/Contact.xml", ObjectViews.class);
    } catch (Exception e) {
      throw Throwables.propagate(e);
    }

    assertNotNull(views);
    assertNotNull(views.getActions());

    MetaStore.resister(views);
    ensureContact();
  }
  protected synchronized void updateCursor(ManagedCursorImpl cursor, Position newPosition)
      throws InterruptedException, ManagedLedgerException {
    checkFenced();
    // First update the metadata store, so that if we don't succeed we have
    // not changed any other state
    store.updateConsumer(name, cursor.getName(), newPosition);
    Position oldPosition = cursor.setAcknowledgedPosition(newPosition);
    cursors.cursorUpdated(cursor);

    if (oldPosition.getLedgerId() != newPosition.getLedgerId()) {
      // Only trigger a trimming when switching to the next ledger
      trimConsumedLedgersInBackground();
    }
  }
  @Test
  public void testView() {

    Action action = MetaStore.getAction("action-view-contact");
    Map<String, Object> context = Maps.newHashMap();

    context.put("id", 1);
    context.put("firstName", "John");
    context.put("lastName", "Smith");

    ActionHandler handler = createHandler(action, context);
    Object value = action.evaluate(handler);

    assertNotNull(value);
  }
  @Test
  public void testRecord() {

    Action action = MetaStore.getAction("action-contact-defaults");
    ActionHandler handler = createHandler(action, null);

    Object value = action.evaluate(handler);
    assertTrue(value instanceof Contact);

    Contact c = (Contact) value;

    assertNotNull(c.getTitle());
    assertEquals("Mr. John Smith", c.getFullName());

    // System.err.println("XXX: " + c);
  }
  @Test
  @SuppressWarnings("all")
  public void testCondition() {

    Action action = MetaStore.getAction("check.dates");
    Map<String, Object> context = Maps.newHashMap();

    context.put("orderDate", new LocalDate("2012-12-10"));
    context.put("createDate", new LocalDate("2012-12-11"));

    ActionHandler handler = createHandler(action, context);
    Object value = action.evaluate(handler);

    assertNotNull(value);
    assertTrue(value instanceof Map);
    assertTrue(!((Map) value).isEmpty());
  }
  @Test
  @SuppressWarnings("all")
  public void testMethod() {

    Action action = MetaStore.getAction("action-contact-greetings");
    Map<String, Object> context = Maps.newHashMap();

    context.put("id", 1);
    context.put("firstName", "John");
    context.put("lastName", "Smith");

    ActionHandler handler = createHandler(action, context);
    Object value = action.evaluate(handler);

    assertNotNull(value);
    assertEquals(
        "Hello World!!!",
        ((Map) ((List<?>) ((ActionResponse) value).getData()).get(0)).get("flash"));
  }
  /*
   * (non-Javadoc)
   *
   * @see org.apache.bookkeeper.mledger.ManagedLedger#openCursor(java.
   * lang.String)
   */
  @Override
  public synchronized ManagedCursor openCursor(String cursorName)
      throws InterruptedException, ManagedLedgerException {
    checkFenced();

    ManagedCursor cursor = cursors.get(cursorName);

    if (cursor == null) {
      // Create a new one and persist it
      Position position = new Position(currentLedger.getId(), currentLedger.getLastAddConfirmed());

      cursor = new ManagedCursorImpl(this, cursorName, position);
      store.updateConsumer(name, cursorName, position);
      cursors.add(cursor);
    }

    log.debug("[{}] Opened new cursor: {}", this.name, cursor);
    return cursor;
  }
  @Test
  @SuppressWarnings("all")
  public void testAttrs() {
    Action action = MetaStore.getAction("action-contact-attrs");
    ActionHandler handler = createHandler(action, null);

    Object value = action.evaluate(handler);
    assertTrue(value instanceof Map);

    Map<String, Object> map = (Map) value;
    Map<String, Object> attrs = (Map) map.get("lastName");

    assertTrue(attrs instanceof Map);
    assertEquals(true, attrs.get("readonly"));
    assertEquals(true, attrs.get("hidden"));

    attrs = (Map) map.get("notes");

    assertTrue(attrs instanceof Map);
  }
  @Test
  public void testEvents() throws Exception {

    FormView view = (FormView) MetaStore.getView("contact-form");
    assertNotNull(view);

    Map<String, Object> context = Maps.newHashMap();

    context.put("firstName", "John");
    context.put("lastName", "Smith");

    String onLoad = view.getOnLoad();
    String onSave = view.getOnSave();

    ActionHandler handler = createHandler(onLoad, context);
    ActionResponse response = handler.execute();
    System.err.println(response.getData());

    handler = createHandler(onSave, context);
    response = handler.execute();
    System.err.println(response.getData());
  }
  @Test
  public void testRpc() {

    Action action = MetaStore.getAction("action-contact-greetings-rpc");
    Map<String, Object> context = Maps.newHashMap();

    context.put("id", 1);
    context.put("firstName", "John");
    context.put("lastName", "Smith");
    context.put("fullName", "John Smith");

    ActionHandler handler = createHandler(action, context);
    Object value = action.evaluate(handler);

    assertNotNull(value);
    assertEquals("Say: John Smith", value);

    value = handler.evaluate("call: com.axelor.meta.web.Hello:say(fullName)");

    assertNotNull(value);
    assertEquals("Say: John Smith", value);
  }
  /**
   * Delete this ManagedLedger completely from the system.
   *
   * @throws Exception
   */
  protected void delete() throws InterruptedException, ManagedLedgerException {
    close();

    synchronized (this) {
      checkFenced();

      try {
        for (LedgerStat ls : ledgers.values()) {
          log.debug("[{}] Deleting ledger {}", name, ls);
          try {
            bookKeeper.deleteLedger(ls.getLedgerId());
          } catch (BKNoSuchLedgerExistsException e) {
            log.warn("[{}] Ledger {} not found when deleting it", name, ls.getLedgerId());
          }
        }
      } catch (BKException e) {
        throw new ManagedLedgerException(e);
      }

      store.removeManagedLedger(name);
    }
  }
  @Test
  public void testMultiRecord() {

    Action action = MetaStore.getAction("action-contact-defaults-multi");
    ActionHandler handler = createHandler(action, null);

    Object value = action.evaluate(handler);
    assertTrue(value instanceof Contact);

    Contact c = (Contact) value;

    assertNotNull(c.getLastName());
    assertNotNull(c.getFirstName());
    assertEquals(c.getFirstName(), c.getLastName());
    assertEquals("Smith", c.getLastName());
    assertEquals("Mr. Smith Smith", c.getFullName());

    assertNotNull(c.getEmail());
    assertNotNull(c.getProEmail());
    assertEquals(c.getProEmail(), c.getEmail());
    assertEquals("*****@*****.**", c.getEmail());
  }
  @Test
  @SuppressWarnings("all")
  public void testAttrsMutli() {
    Action action = MetaStore.getAction("action-contact-attrs-multi");
    ActionHandler handler = createHandler(action, null);

    Object value = action.evaluate(handler);
    assertTrue(value instanceof Map);

    Map<String, Object> map = (Map) value;
    Map<String, Object> attrs = (Map) map.get("lastName");

    assertTrue(attrs instanceof Map);
    assertEquals(true, attrs.get("readonly"));
    assertEquals(true, attrs.get("hidden"));

    attrs = (Map) map.get("notes");

    assertTrue(attrs instanceof Map);
    assertEquals("About Me", attrs.get("title"));

    Map<String, Object> attrsPhone = (Map) map.get("phone");
    Map<String, Object> attrsNotes = (Map) map.get("notes");
    Map<String, Object> attrsBirth = (Map) map.get("dateOfBirth");

    assertTrue(attrs instanceof Map);
    assertEquals(true, attrsPhone.get("hidden"));
    assertEquals(attrsPhone.get("hidden"), attrsNotes.get("hidden"));
    assertEquals(attrsBirth.get("hidden"), attrsNotes.get("hidden"));

    Map<String, Object> attrsFisrtName = (Map) map.get("firstName");
    Map<String, Object> attrsLastName = (Map) map.get("lastName");

    assertTrue(attrs instanceof Map);
    assertEquals(true, attrsFisrtName.get("readonly"));
    assertEquals(attrsFisrtName.get("readonly"), attrsLastName.get("readonly"));
    assertEquals(true, attrsLastName.get("hidden"));
  }
  /*
   * (non-Javadoc)
   *
   * @see
   * org.apache.bookkeeper.client.AsyncCallback.CreateCallback#createComplete
   * (int, org.apache.bookkeeper.client.LedgerHandle, java.lang.Object)
   */
  @Override
  public synchronized void createComplete(int rc, LedgerHandle lh, Object ctx) {
    log.debug("[{}] createComplete rc={} ledger={}", va(name, rc, lh != null ? lh.getId() : -1));

    if (rc != BKException.Code.OK) {
      state = State.ClosedLedger;
      log.error("[{}] Error creating ledger rc={} {}", va(name, rc, BKException.getMessage(rc)));
      ManagedLedgerException status = new ManagedLedgerException(BKException.create(rc));

      // Empty the list of pending requests and make all of them fail
      while (!pendingAddEntries.isEmpty()) {
        pendingAddEntries.poll().failed(status);
      }
    } else {
      log.debug("[{}] Successfully created new ledger {}", name, lh.getId());
      ledgers.put(lh.getId(), new LedgerStat(lh.getId(), 0, 0));
      currentLedger = lh;
      currentLedgerEntries = 0;
      currentLedgerSize = 0;

      MetaStoreCallback<Void> cb =
          new MetaStoreCallback<Void>() {
            public void operationComplete(Void v, Version version) {
              updateLedgersIdsComplete(version);
            }

            public void operationFailed(MetaStoreException e) {
              log.warn("Error updating meta data with the new list of ledgers");
              while (!pendingAddEntries.isEmpty()) {
                pendingAddEntries.poll().failed(e);
              }
            }
          };
      store.asyncUpdateLedgerIds(name, ledgers.values(), ledgersVersion, cb);
    }
  }
  /**
   * Checks whether there are ledger that have been fully consumed and deletes them
   *
   * @throws Exception
   */
  protected void internalTrimConsumedLedgers() {
    // Ensure only one trimming operation is active
    List<LedgerStat> ledgersToDelete = Lists.newArrayList();

    synchronized (this) {
      long slowestReaderLedgerId = -1;
      if (cursors.isEmpty() && currentLedger != null) {
        // At this point the lastLedger will be pointing to the
        // ledger that has just been closed, therefore the +1 to
        // include lastLedger in the trimming.
        slowestReaderLedgerId = currentLedger.getId() + 1;
      } else {
        slowestReaderLedgerId = cursors.getSlowestReaderPosition().getLedgerId();
      }

      for (LedgerStat ls : ledgers.headMap(slowestReaderLedgerId, false).values()) {
        ledgersToDelete.add(ls);
        ledgerCache.invalidate(ls.getLedgerId());
      }

      if (ledgersToDelete.isEmpty()) {
        return;
      }
    }

    // Delete the ledgers _without_ holding the lock on 'this'
    long removedCount = 0;
    long removedSize = 0;

    for (LedgerStat ls : ledgersToDelete) {
      log.info("[{}] Removing ledger {}", name, ls.getLedgerId());
      try {
        bookKeeper.deleteLedger(ls.getLedgerId());
        ++removedCount;
        removedSize += ls.getSize();
      } catch (BKNoSuchLedgerExistsException e) {
        log.warn("[{}] Ledger was already deleted {}", name, ls.getLedgerId());
      } catch (Exception e) {
        log.error("[{}] Error deleting ledger {}", name, ls.getLedgerId());
        return;
      }
    }

    // Update metadata
    try {
      synchronized (this) {
        numberOfEntries.addAndGet(-removedCount);
        totalSize.addAndGet(-removedSize);
        for (LedgerStat ls : ledgersToDelete) {
          ledgers.remove(ls.getLedgerId());
        }

        if (state == State.CreatingLedger) {
          // The list of ledgers is being modified asynchronously, we
          // cannot update it now. In case of a client crash, this
          // will just result in some ledgers to be deleted twice,
          // without any side consequences.
          log.info("[{}] Skipped updating ledger list for concurrent modification", name);
          return;
        }

        ledgersVersion = store.updateLedgersIds(name, ledgers.values(), ledgersVersion);
      }
    } catch (MetaStoreException e) {
      log.error("[{}] Failed to update the list of ledgers after trimming", name, e);
    }
  }