@Override
 public Query<PostEntity> posts() {
   QueryBuilder<PostEntity> queryBuilder = module.newQueryBuilder(PostEntity.class);
   return module
       .currentUnitOfWork()
       .newQuery(queryBuilder)
       .orderBy(templateFor(PostEntity.class).postedAt(), Order.DESCENDING);
 }
  @Test
  public void payAllBills() throws Exception {
    UnitOfWork uow = module.newUnitOfWork(newUsecase("Pay all bills from checking to creditors"));
    try {
      BalanceData source = uow.get(BalanceData.class, CHECKING_ACCOUNT_ID);

      PayBillsContext2 context = module.newObject(PayBillsContext2.class);
      context.bind(source).payBills();
    } finally {
      uow.discard();
    }
  }
Exemple #3
0
    @SuppressWarnings("unchecked")
    private <V> V initializeConfigurationInstance(
        ServiceComposite serviceComposite,
        UnitOfWork uow,
        ServiceDescriptor serviceModel,
        String identity)
        throws InstantiationException {
      Module module = api.moduleOf(serviceComposite);
      Usecase usecase = UsecaseBuilder.newUsecase("Configuration:" + me.identity().get());
      UnitOfWork buildUow = module.newUnitOfWork(usecase);

      EntityBuilder<V> configBuilder =
          buildUow.newEntityBuilder(serviceModel.<V>configurationType(), identity);

      // Check for defaults
      String s = identity + ".properties";
      Class<?> type = first(api.serviceDescriptorFor(serviceComposite).types());
      // Load defaults from classpath root if available
      if (type.getResource(s) == null && type.getResource("/" + s) != null) {
        s = "/" + s;
      }
      InputStream asStream = type.getResourceAsStream(s);
      if (asStream != null) {
        try {
          PropertyMapper.map(asStream, (Composite) configBuilder.instance());
        } catch (IOException e1) {
          InstantiationException exception =
              new InstantiationException("Could not read underlying Properties file.");
          exception.initCause(e1);
          throw exception;
        }
      }

      try {
        configBuilder.newInstance();
        buildUow.complete();

        // Try again
        return (V) findConfigurationInstanceFor(serviceComposite, uow);
      } catch (Exception e1) {
        InstantiationException ex =
            new InstantiationException(
                "Could not instantiate configuration, and no Properties file was found ("
                    + s
                    + ")");
        ex.initCause(e1);
        throw ex;
      }
    }
  @Action
  public Task remove() {
    ConfirmationDialog dialog = module.objectBuilderFactory().newObject(ConfirmationDialog.class);
    dialog.setRemovalMessage(
        i18n.text(
            attachments.getSelectedRows().length > 1
                ? WorkspaceResources.attachments
                : WorkspaceResources.attachment));
    dialogs.showOkCancelHelpDialog(this, dialog, i18n.text(StreamflowResources.confirmation));

    if (dialog.isConfirmed()) {
      final List<AttachmentDTO> removedAttachments = new ArrayList<AttachmentDTO>();
      for (int i : attachments.getSelectedRows()) {
        removedAttachments.add(
            attachmentsModel.getEventList().get(attachments.convertRowIndexToModel(i)));
      }

      return new CommandTask() {
        @Override
        public void command() throws Exception {

          for (AttachmentDTO removedAttachment : removedAttachments) {
            attachmentsModel.removeAttachment(removedAttachment);
          }
        }
      };
    } else return null;
  }
Exemple #5
0
 // WARN Watch this code, see if we can do better, maybe leverage @UnitOfWorkRetry
 @Override
 public void run() {
   System.out.println("Running Schedule");
   Usecase usecase = UsecaseBuilder.newUsecase("ScheduleRunner");
   UnitOfWork uow = module.newUnitOfWork(usecase);
   try {
     Schedule schedule = uow.get(Schedule.class, this.schedule.scheduleIdentity);
     Task task = schedule.task().get();
     schedule = uow.get(Schedule.class, this.schedule.scheduleIdentity);
     try {
       schedule.taskStarting();
       task.run();
       schedule.taskCompletedSuccessfully();
     } catch (RuntimeException ex) {
       schedule.taskCompletedWithException(ex);
     }
     schedulerMixin.dispatchForExecution(schedule);
     uow.complete();
   } catch (UnitOfWorkCompletionException ex) {
   } finally {
     // What should we do if we can't manage the Running flag??
     if (uow.isOpen()) {
       uow.discard();
     }
   }
 }
 @Override
 public void startServer() throws Exception {
   component = new Component();
   component.getServers().add(Protocol.HTTP, 8182);
   RestApplication application = module.newObject(RestApplication.class, component.getContext());
   component.getDefaultHost().attach(application);
   component.start();
 }
Exemple #7
0
 @Override
 public Schedule scheduleOnce(Task task, DateTime runAt, boolean durable) {
   Schedule schedule = scheduleFactory.newOnceSchedule(task, runAt, durable);
   dispatchForExecution(schedule);
   if (durable) {
     Schedules schedules =
         module.currentUnitOfWork().get(Schedules.class, getSchedulesIdentity(me));
     schedules.schedules().add(schedule);
   }
   return schedule;
 }
Exemple #8
0
 @Override
 public Schedule scheduleCron(
     Task task, @CronExpression String cronExpression, DateTime start, boolean durable) {
   Schedule schedule = scheduleFactory.newCronSchedule(task, cronExpression, start, durable);
   if (durable) {
     Schedules schedules =
         module.currentUnitOfWork().get(Schedules.class, getSchedulesIdentity(me));
     schedules.schedules().add(schedule);
   }
   dispatchForExecution(schedule);
   return schedule;
 }
Exemple #9
0
 @Override
 public Schedule scheduleCron(
     Task task, String cronExpression, long initialDelay, boolean durable) {
   DateTime start = new DateTime(System.currentTimeMillis() + initialDelay);
   Schedule schedule = scheduleFactory.newCronSchedule(task, cronExpression, start, durable);
   if (durable) {
     Schedules schedules =
         module.currentUnitOfWork().get(Schedules.class, getSchedulesIdentity(me));
     schedules.schedules().add(schedule);
   }
   dispatchForExecution(schedule);
   return schedule;
 }
 @Override
 public Iterable<TimelineRecord> getNextRecords(int maxResults) {
   SortedSet<TimelineRecord> result = new TreeSet<>();
   UnitOfWork uow = module.currentUnitOfWork();
   String schedulesName = SchedulerMixin.getSchedulesIdentity(scheduler);
   Schedules schedules = uow.get(Schedules.class, schedulesName);
   for (Schedule schedule : schedules.schedules()) {
     Timeline timeline = (Timeline) schedule;
     Iterable<TimelineRecord> lastRecords = timeline.getNextRecords(maxResults);
     Iterables.addAll(result, lastRecords);
   }
   return Iterables.limit(maxResults, result);
 }
Exemple #11
0
    @Override
    public synchronized T get() {
      if (configuration == null) {
        Usecase usecase = UsecaseBuilder.newUsecase("Configuration:" + me.identity().get());
        uow = module.newUnitOfWork(usecase);
        try {
          configuration = this.findConfigurationInstanceFor(me, uow);
        } catch (InstantiationException e) {
          throw new IllegalStateException(e);
        }
      }

      return configuration;
    }
Exemple #12
0
 @Override
 public Schedule scheduleOnce(Task task, int initialSecondsDelay, boolean durable) {
   long now = System.currentTimeMillis();
   Schedule schedule =
       scheduleFactory.newOnceSchedule(
           task, new DateTime(now + initialSecondsDelay * 1000), durable);
   if (durable) {
     Schedules schedules =
         module.currentUnitOfWork().get(Schedules.class, getSchedulesIdentity(me));
     schedules.schedules().add(schedule);
   }
   dispatchForExecution(schedule);
   return schedule;
 }
  @Test(expected = IllegalArgumentException.class)
  public void transferTwiceOfMoneyFromSavingsToChecking() throws Exception {
    UnitOfWork uow =
        module.newUnitOfWork(UsecaseBuilder.newUsecase("Transfer from savings to checking"));

    try {
      // Select source and destination
      BalanceData source = uow.get(BalanceData.class, SAVINGS_ACCOUNT_ID);
      BalanceData destination = uow.get(BalanceData.class, CHECKING_ACCOUNT_ID);

      // Instantiate context and execute enactments with that context
      TransferMoneyContext2 context =
          module.newTransient(TransferMoneyContext2.class).bind(source, destination);

      // Query for double the balance
      final Integer amountToTransfer = context.availableFunds() * 2;

      // Transfer from savings to checking
      context.transfer(amountToTransfer);
    } finally {
      uow.discard();
    }
  }
  @Override
  public Iterable<TimelineRecord> getRecords(DateTime from, DateTime to) {
    SortedSet<TimelineRecord> result = new TreeSet<>();

    UnitOfWork uow = module.currentUnitOfWork();
    String schedulesName = SchedulerMixin.getSchedulesIdentity(scheduler);
    Schedules schedules = uow.get(Schedules.class, schedulesName);
    for (Schedule schedule : schedules.schedules()) {
      Timeline timeline = (Timeline) schedule;
      Iterable<TimelineRecord> lastRecords = timeline.getRecords(from, to);
      Iterables.addAll(result, lastRecords);
    }
    return result;
  }
    public FieldGroupFieldInstance fieldGroupFieldInstanceAdded(
        @Optional DomainEvent event, Field fieldGroup, String id, Field fieldGroupField) {
      EntityBuilder<FieldGroupFieldInstance> builder =
          module
              .unitOfWorkFactory()
              .currentUnitOfWork()
              .newEntityBuilder(FieldGroupFieldInstance.class, id);
      builder.instance().addFieldGroup(fieldGroup);
      builder.instance().addFieldGroupField(fieldGroupField);
      FieldGroupFieldInstance field = builder.newInstance();

      data.groupFields().add(field);
      return field;
    }
 @org.jdesktop.application.Action(block = COMPONENT)
 public Task remove() throws IOException, ResourceException {
   ConfirmationDialog dialog = module.objectBuilderFactory().newObject(ConfirmationDialog.class);
   dialog.setRemovalMessage(((ContactDTO) contacts.getSelectedValue()).name().get());
   dialogs.showOkCancelHelpDialog(this, dialog, i18n.text(StreamflowResources.confirmation));
   if (dialog.isConfirmed()) {
     return new CommandTask() {
       @Override
       public void command() throws Exception {
         model.removeElement(getContactsList().getSelectedIndex());
       }
     };
   } else return null;
 }
  private void printBalances() {
    UnitOfWork uow = module.newUnitOfWork(UsecaseBuilder.newUsecase("Print balances"));

    try {
      System.out.println(
          SAVINGS_ACCOUNT_ID + ":" + uow.get(BalanceData.class, SAVINGS_ACCOUNT_ID).getBalance());
      System.out.println(
          CHECKING_ACCOUNT_ID + ":" + uow.get(BalanceData.class, CHECKING_ACCOUNT_ID).getBalance());
      System.out.println(
          CREDITOR_ID1 + ":" + uow.get(BalanceData.class, CREDITOR_ID1).getBalance());
      System.out.println(
          CREDITOR_ID2 + ":" + uow.get(BalanceData.class, CREDITOR_ID2).getBalance());
    } finally {
      uow.discard();
    }
  }
 public void addFieldGroupFields(Field field) {
   FieldGroupFieldValue value =
       (FieldGroupFieldValue) ((FieldValueDefinition.Data) field).fieldValue().get();
   // find field group definition, and recurse for each field
   Fields.Data fields =
       module
           .unitOfWorkFactory()
           .currentUnitOfWork()
           .get(Fields.Data.class, value.fieldGroup().get().identity());
   for (Field groupField : fields.fields()) {
     Field createdField =
         fieldGroupFieldsAdded(null, field, idGen.generate(Identity.class), groupField);
     createdField.changeDescription(groupField.getDescription());
     fieldGroupFieldInstanceAdded(null, field, idGen.generate(Identity.class), createdField);
   }
 }
 public String restart() {
   Iterable<?> services = module.findServices(first(serviceDescriptor.types()));
   ServiceReference<?> serviceRef =
       (ServiceReference) first(filter(withId(serviceDescriptor.identity()), services));
   if (serviceRef != null) {
     try {
       ((Activation) serviceRef).passivate();
       ((Activation) serviceRef).activate();
       return "Restarted service";
     } catch (Exception e) {
       return "Could not restart service:" + e.getMessage();
     }
   } else {
     return "Could not find service";
   }
 }
Exemple #20
0
 private void loadSchedules() throws UnitOfWorkCompletionException {
   UnitOfWork uow = module.newUnitOfWork();
   try {
     Schedules schedules = uow.get(Schedules.class, getSchedulesIdentity(me));
     for (Schedule schedule : schedules.schedules()) {
       dispatchForExecution(schedule);
     }
   } catch (NoSuchEntityException e) {
     // Create a new Schedules entity for keeping track of them all.
     uow.newEntity(Schedules.class, getSchedulesIdentity(me));
     uow.complete();
   } finally {
     if (uow.isOpen()) {
       uow.discard();
     }
   }
 }
  public CaseTypeDetailView(
      @Service ApplicationContext context,
      @Uses final CaseTypeDetailModel model,
      @Structure Module module) {
    this.model = model;
    valueBinder = module.objectBuilderFactory().newObject(ValueBinder.class);

    FormLayout layout = new FormLayout("150dlu, 2dlu, 350", "pref, pref, pref, pref, pref, pref");
    setLayout(layout);
    setMaximumSize(new Dimension(Short.MAX_VALUE, 50));
    DefaultFormBuilder builder = new DefaultFormBuilder(layout, this);

    ownerName = new StreamflowSelectableLabel();

    builder.append(new JLabel(" "));
    builder.nextLine();

    builder.appendSeparator(i18n.text(AdministrationResources.casetype_separator));

    builder.nextLine();

    builder.append(
        i18n.text(AdministrationResources.owner_name_label),
        valueBinder.bind("ownerName", ownerName));
    builder.nextLine();

    ownerId = new StreamflowSelectableLabel();

    builder.append(
        i18n.text(AdministrationResources.owner_id_label), valueBinder.bind("ownerId", ownerId));

    builder.nextLine();
    builder.append(new JLabel(" "));
    builder.nextLine();

    builder.appendSeparator(i18n.text(AdministrationResources.casetype_id_separator));

    builder.nextLine();

    caseTypeId = new StreamflowSelectableLabel();

    builder.append(i18n.text(AdministrationResources.id_label), valueBinder.bind("id", caseTypeId));

    new RefreshWhenShowing(this, this);
  }
Exemple #22
0
  public static void setUpTest(Module module) {
    Connection connection = null;
    try {

      DataSource ds = module.findService(DataSource.class).get();
      connection = ds.getConnection();
      Assume.assumeNotNull(connection);

    } catch (Throwable t) {

      t.printStackTrace();
      Assume.assumeNoException(t);

    } finally {

      SQLUtil.closeQuietly(connection);
    }
  }
    /**
     * Try to determine what address from the to address list should be used as main TO address for
     * the different EmailReceiver's. In case the references header is null we try to find a
     * matching email access point.
     *
     * @param recipients The recipients from the TO address list
     * @param references The references header
     * @return A hopefully valid email address as a string
     */
    private String toaddress(final Address[] recipients, String references) {
      String result = "";
      // No recipients found return n/a
      if (recipients == null || recipients.length == 0) return "n/a";

      if (!hasStreamflowReference(references)) {
        Organizations.Data organizations =
            module
                .unitOfWorkFactory()
                .currentUnitOfWork()
                .get(Organizations.Data.class, OrganizationsEntity.ORGANIZATIONS_ID);
        EmailAccessPoints.Data emailAccessPoints =
            (EmailAccessPoints.Data) organizations.organization().get();

        Iterable<EmailAccessPoint> possibleAccesspoints =
            Iterables.filter(
                new Specification<EmailAccessPoint>() {
                  public boolean satisfiedBy(final EmailAccessPoint accessPoint) {
                    return Iterables.matchesAny(
                        new Specification<Address>() {
                          public boolean satisfiedBy(Address address) {
                            return ((InternetAddress) address)
                                .getAddress()
                                .equalsIgnoreCase(accessPoint.getDescription());
                          }
                        },
                        Arrays.asList(recipients));
                  }
                },
                emailAccessPoints.emailAccessPoints().toList());

        if (Iterables.count(possibleAccesspoints) > 0)
          result = Iterables.first(possibleAccesspoints).getDescription();
        else result = ((InternetAddress) recipients[0]).getAddress();

      } else {
        result = ((InternetAddress) recipients[0]).getAddress();
      }

      return Strings.empty(result) ? "n/a" : result.toLowerCase();
    }
Exemple #24
0
    @Override
    public void insertInitialData() throws Exception {
      UnitOfWork unitOfWork = module.newUnitOfWork();

      try {
        unitOfWork.get(Forums.class, Forums.FORUMS_ID);
      } catch (NoSuchEntityException e) {
        unitOfWork.newEntity(Forums.class, Forums.FORUMS_ID);
      }

      try {
        unitOfWork.get(Users.class, Users.USERS_ID);
      } catch (NoSuchEntityException e) {
        unitOfWork.newEntity(Users.class, Users.USERS_ID);
      }

      try {
        unitOfWork.complete();
      } catch (UnitOfWorkCompletionException e) {
        throw new InitializationException(e);
      }
    }
    public Field fieldGroupFieldsAdded(
        @Optional DomainEvent event, Field fieldGroup, String id, Field fieldGroupField) {

      FieldValueDefinition.Data definition = (FieldValueDefinition.Data) fieldGroupField;

      EntityBuilder<Field> fieldBuilder =
          module.unitOfWorkFactory().currentUnitOfWork().newEntityBuilder(Field.class, id);
      fieldBuilder.instanceFor(Mandatory.Data.class).mandatory().set(fieldGroupField.isMandatory());
      fieldBuilder.instanceFor(Notable.Data.class).note().set(fieldGroupField.getNote());
      fieldBuilder
          .instanceFor(Describable.Data.class)
          .description()
          .set(fieldGroupField.getDescription());
      fieldBuilder
          .instanceFor(Datatype.Data.class)
          .datatype()
          .set(((Datatype.Data) fieldGroupField).datatype().get());
      fieldBuilder
          .instanceFor(Statistical.Data.class)
          .statistical()
          .set(((Statistical.Data) fieldGroupField).statistical().get());

      FieldValue fieldValue = definition.fieldValue().get();
      fieldBuilder.instanceFor(FieldValueDefinition.Data.class).fieldValue().set(fieldValue);

      String fieldId =
          Classes.interfacesOf(fieldValue.getClass()).iterator().next().getSimpleName();
      fieldId =
          fieldGroup.getDescription()
              + "_"
              + fieldId.substring(0, fieldId.length() - "FieldValue".length());
      fieldId += data.groupFields().count() + 1;
      fieldBuilder.instanceFor(FieldId.Data.class).fieldId().set(fieldId);

      Field createdFieldGroupField = fieldBuilder.newInstance();

      return createdFieldGroupField;
    }
  private static void bootstrapData() throws Exception {
    UnitOfWork uow = module.newUnitOfWork(newUsecase("Bootstrap data"));
    try {
      SavingsAccountEntity account = uow.newEntity(SavingsAccountEntity.class, SAVINGS_ACCOUNT_ID);
      account.increasedBalance(1000);

      CheckingAccountEntity checkingAccount =
          uow.newEntity(CheckingAccountEntity.class, CHECKING_ACCOUNT_ID);
      checkingAccount.increasedBalance(200);

      // Create some creditor debt
      BalanceData bakerAccount = uow.newEntity(CreditorEntity.class, CREDITOR_ID1);
      bakerAccount.decreasedBalance(50);

      BalanceData butcherAccount = uow.newEntity(CreditorEntity.class, CREDITOR_ID2);
      butcherAccount.decreasedBalance(90);

      // Save
      uow.complete();
    } finally {
      uow.discard();
    }
  }
    private AttachedFileValue createAttachedFileValue(Date sentDate, BodyPart part)
        throws MessagingException, IOException {
      // Create attachment
      ValueBuilder<AttachedFileValue> attachmentBuilder =
          module.valueBuilderFactory().newValueBuilder(AttachedFileValue.class);

      AttachedFileValue prototype = attachmentBuilder.prototype();
      // check contentType and fetch just the first part if necessary
      String contentType = "";
      if (part.getContentType().indexOf(';') == -1) contentType = part.getContentType();
      else contentType = part.getContentType().substring(0, part.getContentType().indexOf(';'));

      prototype.mimeType().set(contentType);
      prototype.modificationDate().set(sentDate);
      String fileName = part.getFileName();
      prototype.name().set(fileName == null ? "Nofilename" : MimeUtility.decodeText(fileName));
      prototype.size().set((long) part.getSize());

      InputStream inputStream = part.getInputStream();
      String id = attachmentStore.storeAttachment(Inputs.byteBuffer(inputStream, 4096));
      String uri = "store:" + id;
      prototype.uri().set(uri);
      return attachmentBuilder.newInstance();
    }
Exemple #28
0
 public Query<Board> boards() {
   return module.newQueryBuilder(Board.class).newQuery(self.boards());
 }
Exemple #29
0
 protected <T> T role(Class<T> roleType, Object data) {
   return module.newObject(roleType, data);
 }
    public void run() {
      Thread.currentThread().setContextClassLoader(getClass().getClassLoader());

      if (!circuitBreaker.isOn()) return; // Don't try - circuit breaker is off

      boolean expunge = config.configuration().deleteMailOnInboxClose().get();
      if (config.configuration().debug().get()) {
        logger.info("Checking email");
        logger.info("Delete mail on close - " + expunge);
      }

      Session session = javax.mail.Session.getInstance(props, authenticator);
      session.setDebug(config.configuration().debug().get());

      Usecase usecase = newUsecase("Receive Mail");
      UnitOfWork uow = null;
      Store store = null;
      Folder inbox = null;
      Folder archive = null;
      boolean archiveExists = false;
      List<Message> copyToArchive = new ArrayList<Message>();
      MimeMessage internalMessage = null;

      try {
        store = session.getStore(url);
        store.connect();

        inbox = store.getFolder("INBOX");
        inbox.open(Folder.READ_WRITE);

        javax.mail.Message[] messages = inbox.getMessages();
        FetchProfile fp = new FetchProfile();
        //            fp.add( "In-Reply-To" );
        inbox.fetch(messages, fp);

        // check if the archive folder is configured and exists
        if (!Strings.empty(config.configuration().archiveFolder().get())
            && config.configuration().protocol().get().startsWith("imap")) {
          archive = store.getFolder(config.configuration().archiveFolder().get());

          // if not exists - create
          if (!archive.exists()) {
            archive.create(Folder.HOLDS_MESSAGES);
            archiveExists = true;
          } else {
            archiveExists = true;
          }

          archive.open(Folder.READ_WRITE);
        }

        for (javax.mail.Message message : messages) {
          int tries = 0;
          while (tries < 3) {
            uow = module.unitOfWorkFactory().newUnitOfWork(usecase);

            ValueBuilder<EmailValue> builder =
                module.valueBuilderFactory().newValueBuilder(EmailValue.class);

            try {
              // Force a complete fetch of the message by cloning it to a internal MimeMessage
              // to avoid "javax.mail.MessagingException: Unable to load BODYSTRUCTURE" problems
              // f.ex. experienced if the message contains a windows .eml file as attachment!

              // Beware that all flag and folder operations have to be made on the original message
              // and not on the internal one!!
              internalMessage = new MimeMessage((MimeMessage) message);

              Object content = internalMessage.getContent();

              // Get email fields
              builder
                  .prototype()
                  .from()
                  .set(((InternetAddress) internalMessage.getFrom()[0]).getAddress());
              builder
                  .prototype()
                  .fromName()
                  .set(((InternetAddress) internalMessage.getFrom()[0]).getPersonal());
              builder
                  .prototype()
                  .subject()
                  .set(internalMessage.getSubject() == null ? "" : internalMessage.getSubject());

              // Get headers
              for (Header header :
                  Iterables.iterable((Enumeration<Header>) internalMessage.getAllHeaders())) {
                builder.prototype().headers().get().put(header.getName(), header.getValue());
              }

              // Get all recipients in order - TO, CC, BCC
              // and provide it to the toaddress method to pick the first possible valid adress
              builder
                  .prototype()
                  .to()
                  .set(
                      toaddress(
                          internalMessage.getAllRecipients(),
                          builder.prototype().headers().get().get("References")));

              builder.prototype().messageId().set(internalMessage.getHeader("Message-ID")[0]);

              // Get body and attachments
              String body = "";
              // set content initially so it never can become null
              builder.prototype().content().set(body);

              if (content instanceof String) {
                body = content.toString();
                builder.prototype().content().set(body);
                String contentTypeString = cleanContentType(internalMessage.getContentType());
                builder.prototype().contentType().set(contentTypeString);
                if (Translator.HTML.equalsIgnoreCase(contentTypeString)) {
                  builder.prototype().contentHtml().set(body);
                }

              } else if (content instanceof Multipart) {
                handleMultipart((Multipart) content, internalMessage, builder);
              } else if (content instanceof InputStream) {
                content = new MimeMessage(session, (InputStream) content).getContent();
                ByteArrayOutputStream baos = new ByteArrayOutputStream();
                Inputs.byteBuffer((InputStream) content, 4096).transferTo(Outputs.byteBuffer(baos));

                String data = new String(baos.toByteArray(), "UTF-8");
                // Unknown content type - abort
                // and create failure case
                String subj = "Unkonwn content type: " + internalMessage.getSubject();
                builder
                    .prototype()
                    .subject()
                    .set(subj.length() > 50 ? subj.substring(0, 50) : subj);
                builder.prototype().content().set(body);
                builder.prototype().contentType().set(internalMessage.getContentType());
                systemDefaults.createCaseOnEmailFailure(builder.newInstance());
                copyToArchive.add(message);
                if (expunge) message.setFlag(Flags.Flag.DELETED, true);

                uow.discard();
                tries = 3;
                continue;
              } else {
                // Unknown content type - abort
                // and create failure case
                String subj = "Unkonwn content type: " + internalMessage.getSubject();
                builder
                    .prototype()
                    .subject()
                    .set(subj.length() > 50 ? subj.substring(0, 50) : subj);
                builder.prototype().content().set(body);
                builder.prototype().contentType().set(internalMessage.getContentType());
                systemDefaults.createCaseOnEmailFailure(builder.newInstance());
                copyToArchive.add(message);
                if (expunge) message.setFlag(Flags.Flag.DELETED, true);

                uow.discard();
                logger.error(
                    "Could not parse emails: unknown content type " + content.getClass().getName());
                tries = 3;
                continue;
              }

              // make sure mail content fit's into statistic database - truncate on 65.500
              // characters.
              if (builder.prototype().content().get().length() > 65000) {
                builder
                    .prototype()
                    .content()
                    .set(builder.prototype().content().get().substring(0, 65000));
              }

              // try to reveal if it is a smpt error we are looking at
              // X-Failed-Recipients is returned by Gmail
              // X-FC-MachineGenerated is returned by FirstClass
              // Exchange is following RFC 6522 -  The Multipart/Report Media Type for
              // the Reporting of Mail System Administrative Messages
              boolean isSmtpErrorReport =
                  !Strings.empty(builder.prototype().headers().get().get("X-Failed-Recipients"))
                      || (!Strings.empty(
                              builder.prototype().headers().get().get("X-FC-MachineGenerated"))
                          && "true"
                              .equals(
                                  builder.prototype().headers().get().get("X-FC-MachineGenerated")))
                      || !Strings.empty(
                          new ContentType(builder.prototype().headers().get().get("Content-Type"))
                              .getParameter("report-type"));

              if (isSmtpErrorReport) {
                // This is a mail bounce due to SMTP error - create support case.
                String subj = "Undeliverable mail: " + builder.prototype().subject().get();

                builder
                    .prototype()
                    .subject()
                    .set(subj.length() > 50 ? subj.substring(0, 50) : subj);
                systemDefaults.createCaseOnEmailFailure(builder.newInstance());
                copyToArchive.add(message);
                if (expunge) message.setFlag(Flags.Flag.DELETED, true);

                uow.discard();
                logger.error("Received a mail bounce reply: " + body);
                tries = 3;
                continue;
              }

              if (builder.prototype().to().get().equals("n/a")) {
                // This is a mail has no to address - create support case.

                String subj = "No TO address: " + builder.prototype().subject().get();

                builder
                    .prototype()
                    .subject()
                    .set(subj.length() > 50 ? subj.substring(0, 50) : subj);
                systemDefaults.createCaseOnEmailFailure(builder.newInstance());
                copyToArchive.add(message);
                if (expunge) message.setFlag(Flags.Flag.DELETED, true);

                uow.discard();
                logger.error("Received a mail without TO address: " + body);
                tries = 3;
                continue;
              }

              mailReceiver.receivedEmail(null, builder.newInstance());

              try {
                logger.debug("This is try " + tries);
                uow.complete();
                tries = 3;
              } catch (ConcurrentEntityModificationException ceme) {
                if (tries < 2) {
                  logger.debug("Encountered ConcurrentEntityModificationException - try again ");
                  // discard uow and try again
                  uow.discard();
                  tries++;
                  continue;

                } else {
                  logger.debug("Rethrowing ConcurrentEntityModification.Exception");
                  tries++;
                  throw ceme;
                }
              }

              copyToArchive.add(message);
              // remove mail on success if expunge is true
              if (expunge) message.setFlag(Flags.Flag.DELETED, true);

            } catch (Throwable e) {
              String subj = "Unknown error: " + internalMessage.getSubject();
              builder.prototype().subject().set(subj.length() > 50 ? subj.substring(0, 50) : subj);

              StringBuilder content = new StringBuilder();
              content.append("Error Message: " + e.getMessage());
              content.append("\n\rStackTrace:\n\r");
              for (StackTraceElement trace : Arrays.asList(e.getStackTrace())) {
                content.append(trace.toString() + "\n\r");
              }

              builder.prototype().content().set(content.toString());
              // since we create the content of the message our self it's ok to set content type
              // always to text/plain
              builder.prototype().contentType().set("text/plain");

              // Make sure to address has some value before vi create a case!!
              if (builder.prototype().to().get() == null) {
                builder.prototype().to().set("n/a");
              }
              systemDefaults.createCaseOnEmailFailure(builder.newInstance());
              copyToArchive.add(message);
              if (expunge) message.setFlag(Flags.Flag.DELETED, true);

              uow.discard();
              logger.error("Could not parse emails", e);
              tries = 3;
            }
          }
        }

        // copy message to archive if archive exists
        if (archiveExists) {
          inbox.copyMessages(copyToArchive.toArray(new Message[0]), archive);
          archive.close(false);
        }

        inbox.close(config.configuration().deleteMailOnInboxClose().get());

        store.close();

        if (config.configuration().debug().get()) {
          logger.info("Checked email");
        }

        circuitBreaker.success();
      } catch (Throwable e) {
        logger.error("Error in mail receiver: ", e);
        circuitBreaker.throwable(e);

        try {
          if (inbox != null && inbox.isOpen()) inbox.close(false);

          if (store != null && store.isConnected()) store.close();
        } catch (Throwable e1) {
          logger.error("Could not close inbox", e1);
        }
      }
    }