private String generateDataName() {
   return Messages.Data
       + (ModelHelper.getAllItemsOfType(
                   ModelHelper.getParentProcess(element),
                   SimulationPackage.eINSTANCE.getSimulationData())
               .size()
           + 1);
 }
  private FileWidgetInputType createUseDocumentButton(
      TabbedPropertySheetWidgetFactory widgetFactory, final Composite radioComposite) {
    FileWidgetInputType initialInputType = element.getInputType();
    if (!ModelHelper.isAnEntryPageFlowOnAPool(ModelHelper.getParentForm(element))) {
      useDocumentButton =
          widgetFactory.createButton(radioComposite, Messages.useDocument, SWT.RADIO);
      useDocumentButton.addSelectionListener(
          new SelectionAdapter() {

            @Override
            public void widgetSelected(org.eclipse.swt.events.SelectionEvent e) {
              if (initialValueSection != null && !initialValueSection.isDisposed()) {
                if (useDocumentButton.getSelection()
                    && (element.getInputType() != FileWidgetInputType.DOCUMENT
                        || element.isDuplicate() != multiple
                        || initialValueSection.getClient() == null)) {
                  boolean recreate = false;
                  if (initialValueSection.getClient() == null
                      || element.getInputType() == FileWidgetInputType.RESOURCE) {
                    recreate = true;
                  }
                  editingDomain
                      .getCommandStack()
                      .execute(
                          SetCommand.create(
                              editingDomain,
                              element,
                              FormPackage.Literals.FILE_WIDGET__INPUT_TYPE,
                              FileWidgetInputType.DOCUMENT));
                  if (recreate) {
                    if (initialValueSection.getClient() != null) {
                      initialValueSection.getClient().dispose();
                    }
                    multiple = element.isDuplicate();
                    initialValueSection.setClient(
                        createInputExpressionComposite(
                            initialValueSection,
                            FileGridPropertySectionContribution.this.widgetFactory));

                    initialValueSection.setExpanded(true);
                    bindFields();
                  }
                }
              }
            }
          });
    } else {
      initialInputType = FileWidgetInputType.URL;
    }
    return initialInputType;
  }
  protected void addProcessImage(
      final BusinessArchiveBuilder builder, final AbstractProcess process) throws CoreException {
    if (PlatformUI.isWorkbenchRunning()) {
      final String processName = process.getName() + "_" + process.getVersion();
      final String path = processName + ".png"; // $NON-NLS-1$

      try {
        Diagram diagram = ModelHelper.getDiagramFor(ModelHelper.getMainProcess(process));
        if (diagram == null) {
          return; // DON'T ADD IMAGE, DON'T THROW EXCEPTION FOR TESTS PURPUSES
        }
        final ResourceSet resourceSet = new ResourceSetImpl();
        final TransactionalEditingDomain editingDomain =
            CustomDiagramEditingDomainFactory.getInstance().createEditingDomain(resourceSet);
        final Resource resource = resourceSet.createResource(diagram.eResource().getURI());
        try {
          resource.load(resourceSet.getLoadOptions());
        } catch (final IOException e1) {
          BonitaStudioLog.error(e1);
        }
        diagram = (Diagram) resource.getEObject(diagram.eResource().getURIFragment(diagram));
        final CopyToImageUtilEx copyToImageUtil = new CopyToImageUtilEx();
        byte[] imageBytes = null;
        try {
          imageBytes =
              copyToImageUtil.copyToImageByteArray(
                  diagram,
                  process,
                  ImageFileFormat.PNG,
                  Repository.NULL_PROGRESS_MONITOR,
                  new PreferencesHint("exportToImage"),
                  true);
        } catch (final Exception e) {
          BonitaStudioLog.error(e);
          return;
        } finally {
          editingDomain.dispose();
        }
        if (imageBytes != null) {
          try {
            builder.addExternalResource(new BarResource(path, imageBytes));
          } catch (final Exception e) {
            BonitaStudioLog.log("Process image file generation has failed"); // $NON-NLS-1$
          }
        }
      } catch (final Exception e) {
        BonitaStudioLog.error(e);
      }
    }
  }
  @Before
  public void setUp() throws Exception {
    if (pool == null) {
      final NewDiagramCommandHandler newDiagram = new NewDiagramCommandHandler();
      final DiagramFileStore diagramFileStore = newDiagram.execute(null);
      pool = (AbstractProcess) EcoreUtil.copy(diagramFileStore.getContent()).getElements().get(0);
      final Configuration conf = ConfigurationFactory.eINSTANCE.createConfiguration();

      conf.setName(CONF_NAME);
      pool.getConfigurations().add(conf);

      final Parameter p1 = ParameterFactory.eINSTANCE.createParameter();
      p1.setName("dbUrl");
      p1.setTypeClassname(String.class.getName());
      pool.getParameters().add(p1);

      final Parameter p2 = ParameterFactory.eINSTANCE.createParameter();
      p2.setName("password");
      p2.setTypeClassname(String.class.getName());
      pool.getParameters().add(p2);

      final Parameter p3 = ParameterFactory.eINSTANCE.createParameter();
      p3.setName("port");
      p3.setTypeClassname(Integer.class.getName());
      pool.getParameters().add(p3);

      pool.getFormMapping().setType(FormMappingType.LEGACY);
      for (final Task t : ModelHelper.getAllElementOfTypeIn(pool, Task.class)) {
        t.getFormMapping().setType(FormMappingType.LEGACY);
      }

      new ConfigurationSynchronizer(pool, pool.getConfigurations().get(0)).synchronize();
    }
  }
  protected void editData() {
    final IStructuredSelection selection = (IStructuredSelection) dataTableViewer.getSelection();
    if (onlyOneElementSelected(selection)) {
      final Data selectedData = (Data) selection.getFirstElement();
      if (selectedData.eContainer() == null) {
        final AbstractProcess parentProcess = ModelHelper.getParentProcess(eObject);
        BonitaStudioLog.error(
            "Investigation trace for issue BS-11552:\n"
                + "The context was not initialized.\n "
                + "Please report the issue with details and attached impacted process.\n"
                + "data: "
                + (selectedData != null ? selectedData.getName() : "null data")
                + "\n"
                + "From diagram:"
                + (parentProcess != null ? parentProcess.getName() : "No process found."),
            DataPlugin.PLUGIN_ID);
      }

      final DataWizard wizard =
          new DataWizard(
              getEditingDomain(),
              selectedData,
              getDataFeature(),
              getDataFeatureToCheckUniqueID(),
              getShowAutoGenerateForm());
      wizard.setIsPageFlowContext(isPageFlowContext());
      wizard.setIsOverviewContext(isOverViewContext());
      new CustomWizardDialog(
              Display.getDefault().getActiveShell(), wizard, IDialogConstants.OK_LABEL)
          .open();
      dataTableViewer.refresh();
    }
  }
  @Test
  public void testCustomonnectorMigrationWithGetterCustom() throws Exception {
    final URL url = TestCustomConnectorMigrationUseCase.class.getResource("fab--1.0.bar");
    final File migratedProc = BarImporterTestUtil.migrateBar(url);
    assertNotNull("Fail to migrate bar file", migratedProc);
    assertNotNull("Fail to migrate bar file", migratedProc.exists());
    final Resource resource = BarImporterTestUtil.assertIsLoadable(migratedProc);
    final MainProcess mainProc = BarImporterTestUtil.getMainProcess(resource);

    final ConnectorDefRepositoryStore defStore =
        (ConnectorDefRepositoryStore)
            RepositoryManager.getInstance().getRepositoryStore(ConnectorDefRepositoryStore.class);
    assertNotNull(defStore.getDefinition("fabulous_connector", "1.0.0"));

    final ConnectorImplRepositoryStore implStore =
        (ConnectorImplRepositoryStore)
            RepositoryManager.getInstance().getRepositoryStore(ConnectorImplRepositoryStore.class);
    ConnectorImplementation implementation =
        implStore.getImplementation("fabulous_connector-impl", "1.0.0");
    assertNotNull(implementation);

    final ConnectorSourceRepositoryStore sourceStore =
        (ConnectorSourceRepositoryStore)
            RepositoryManager.getInstance()
                .getRepositoryStore(ConnectorSourceRepositoryStore.class);
    assertNotNull(sourceStore.getChild(implementation.getImplementationClassname()));

    final List<Connector> connectors =
        ModelHelper.getAllItemsOfType(mainProc, ProcessPackage.Literals.CONNECTOR);
    assertEquals("Invalid number of connector", 1, connectors.size());
  }
 /*
  * (non-Javadoc)
  * @see org.eclipse.gmf.runtime.diagram.ui.properties.sections.
  * AbstractModelerPropertySection#getEObject()
  */
 @Override
 protected EObject getEObject() {
   final EObject eObject = super.getEObject();
   if (eObject instanceof Lane) {
     return ModelHelper.getParentProcess(eObject);
   }
   return eObject;
 }
 private void expressionButtonListener(final EObject context) {
   final ParameterWizardDialog parameterDialog =
       new ParameterWizardDialog(
           Display.getCurrent().getActiveShell(),
           new AddParameterWizard(
               ModelHelper.getParentProcess(context), TransactionUtil.getEditingDomain(context)));
   if (parameterDialog.open() == Dialog.OK) {
     fillViewerInput(context);
   }
 }
  protected void bindFields() {
    if (dataBindingContext != null) {
      dataBindingContext.dispose();
    }
    dataBindingContext = new EMFDataBindingContext();
    if (downloadOnly != null) {
      if (ModelHelper.getForm(element) instanceof ViewForm) {
        downloadOnly.setSelection(true);
        downloadOnly.setEnabled(false);
      } else {
        dataBindingContext.bindValue(
            SWTObservables.observeSelection(downloadOnly),
            EMFEditObservables.observeValue(
                editingDomain, element, FormPackage.Literals.FILE_WIDGET__DOWNLOAD_ONLY));
      }
    }

    dataBindingContext.bindValue(
        SWTObservables.observeSelection(imagePreview),
        EMFEditObservables.observeValue(
            editingDomain, element, FormPackage.Literals.FILE_WIDGET__USE_PREVIEW));

    IObservableValue value =
        EMFObservables.observeValue(element, FormPackage.Literals.DUPLICABLE__DUPLICATE);

    value.addValueChangeListener(
        new IValueChangeListener() {

          public void handleValueChange(ValueChangeEvent arg0) {
            if (useDocumentButton != null
                && !useDocumentButton.isDisposed()
                && element.getInputType() == FileWidgetInputType.DOCUMENT) {
              useDocumentButton.notifyListeners(SWT.Selection, new Event());
              /*}else if(!useResourceButton.isDisposed() && element.getInputType() == FileWidgetInputType.URL){
              useURLButton.notifyListeners(SWT.Selection,new Event());*/
            } else if (!useResourceButton.isDisposed()
                && element.getInputType() == FileWidgetInputType.RESOURCE) {
              useResourceButton.notifyListeners(SWT.Selection, new Event());
            }
            if (inputExpressionViewer != null
                && !getInputExpressionHint()
                    .equals(inputExpressionViewer.getMessage(IStatus.INFO))) {
              inputExpressionViewer.setMessage(getInputExpressionHint(), IStatus.INFO);
            }
          }
        });

    bindInputExpressionViewer();
    bindResourceText();
  }
示例#10
0
 public DataWizard(
     EObject container,
     EStructuralFeature dataContainmentFeature,
     Set<EStructuralFeature> featureToCheckForUniqueID,
     boolean showAutogenerateForm) {
   initDataWizard(dataContainmentFeature, showAutogenerateForm);
   this.container = container;
   dataWorkingCopy = ProcessFactory.eINSTANCE.createData();
   dataWorkingCopy.setDataType(
       ModelHelper.getDataTypeForID(container, DataTypeLabels.stringDataType));
   editMode = false;
   this.featureToCheckForUniqueID = new HashSet<EStructuralFeature>();
   this.featureToCheckForUniqueID.add(dataContainmentFeature);
   setWindowTitle(Messages.newVariable);
 }
 /* (non-Javadoc)
  * @see org.eclipse.jface.viewers.EditingSupport#setValue(java.lang.Object, java.lang.Object)
  */
 @Override
 protected void setValue(Object element, Object value) {
   if (element != null && value != null && transactionalEditingDomain != null) {
     AbstractProcess process = ModelHelper.getParentProcess((EObject) element);
     if (process != null) {
       transactionalEditingDomain
           .getCommandStack()
           .execute(
               SetCommand.create(
                   transactionalEditingDomain,
                   element,
                   ProcessPackage.Literals.ELEMENT__DOCUMENTATION,
                   value));
       getViewer().refresh();
     }
   }
 }
 @Override
 protected List<Connector> getExistingConnectors(AbstractProcess process) {
   List<Connector> connectors =
       ModelHelper.getAllItemsOfType(process, ProcessPackage.Literals.CONNECTOR);
   Set<Connector> toRemove = new HashSet<Connector>();
   for (Connector c : connectors) {
     if (c instanceof ActorFilter) {
       toRemove.add(c);
     }
     if (c.eContainer() instanceof Expression) {
       Expression exp = (Expression) c.eContainer();
       if (!ExpressionConstants.CONNECTOR_TYPE.equals(exp.getType())) {
         toRemove.add(c);
       }
     }
   }
   connectors.removeAll(toRemove);
   return connectors;
 }
示例#13
0
 public Configuration getConfiguration(final AbstractProcess process, String configurationId) {
   Configuration configuration = null;
   final ProcessConfigurationRepositoryStore processConfStore =
       RepositoryManager.getInstance()
           .getRepositoryStore(ProcessConfigurationRepositoryStore.class);
   if (configurationId == null) {
     configurationId =
         ConfigurationPlugin.getDefault()
             .getPreferenceStore()
             .getString(ConfigurationPreferenceConstants.DEFAULT_CONFIGURATION);
   }
   if (configurationId.equals(ConfigurationPreferenceConstants.LOCAL_CONFIGURAITON)) {
     final String id = ModelHelper.getEObjectID(process);
     IRepositoryFileStore file = processConfStore.getChild(id + ".conf");
     if (file == null) {
       file = processConfStore.createRepositoryFileStore(id + ".conf");
       configuration = ConfigurationFactory.eINSTANCE.createConfiguration();
       configuration.setName(configurationId);
       configuration.setVersion(ModelVersion.CURRENT_VERSION);
       file.save(configuration);
     }
     try {
       configuration = (Configuration) file.getContent();
     } catch (final ReadFileStoreException e) {
       BonitaStudioLog.error("Failed to read process configuration", e);
     }
   } else {
     for (final Configuration conf : process.getConfigurations()) {
       if (configurationId.equals(conf.getName())) {
         configuration = conf;
       }
     }
   }
   if (configuration == null) {
     configuration = ConfigurationFactory.eINSTANCE.createConfiguration();
     configuration.setName(configurationId);
     configuration.setVersion(ModelVersion.CURRENT_VERSION);
   }
   // Synchronize configuration with definition
   new ConfigurationSynchronizer(process, configuration).synchronize();
   return configuration;
 }
 private void addNewKPIConnectorDefinition(
     Configuration configuration,
     AbstractProcess process,
     CompoundCommand cc,
     EditingDomain editingDomain) {
   List<DatabaseKPIBinding> kpiBindings =
       ModelHelper.getAllItemsOfType(process, KpiPackage.Literals.DATABASE_KPI_BINDING);
   if (!kpiBindings.isEmpty()) {
     String defId = DB_CONNECTOR_FOR_KPI_ID;
     String defVersion = DB_CONNECTOR_VERSION;
     boolean exists = false;
     for (DefinitionMapping association : configuration.getDefinitionMappings()) {
       if (FragmentTypes.CONNECTOR.equals(association.getType())
           && association.getDefinitionId().equals(defId)
           && association.getDefinitionVersion().equals(defVersion)) {
         exists = true;
         updateAssociation(configuration, association, cc, editingDomain);
         break;
       }
     }
     if (!exists) {
       DefinitionMapping newAssociation = ConfigurationFactory.eINSTANCE.createDefinitionMapping();
       newAssociation.setDefinitionId(defId);
       newAssociation.setDefinitionVersion(defVersion);
       newAssociation.setType(getFragmentContainerId());
       editingDomain
           .getCommandStack()
           .execute(
               AddCommand.create(
                   editingDomain,
                   configuration,
                   ConfigurationPackage.Literals.CONFIGURATION__DEFINITION_MAPPINGS,
                   newAssociation));
       updateAssociation(configuration, newAssociation, cc, editingDomain);
     }
   }
 }
  /*
   * (non-Javadoc)
   *
   * @seeorg.bonitasoft.studio.common.properties.
   * IExtensibleGridPropertySectionContribution
   * #createControl(org.eclipse.swt.widgets.Composite,
   * org.eclipse.ui.views.properties.tabbed.TabbedPropertySheetWidgetFactory,
   * org.bonitasoft.studio.common.properties.ExtensibleGridPropertySection)
   */
  public void createControl(
      Composite mainComposite,
      TabbedPropertySheetWidgetFactory widgetFactory,
      ExtensibleGridPropertySection extensibleGridPropertySection) {

    this.widgetFactory = widgetFactory;
    mainComposite.setLayoutData(GridDataFactory.fillDefaults().grab(true, true).create());
    int col = 3;
    if (ModelHelper.isAnEntryPageFlowOnAPool(ModelHelper.getParentForm(element))) {
      col = 2;
    }
    mainComposite.setLayout(GridLayoutFactory.fillDefaults().numColumns(3).create());

    downloadOnly = widgetFactory.createButton(mainComposite, Messages.downloadOnly, SWT.CHECK);
    imagePreview = widgetFactory.createButton(mainComposite, Messages.previewAttachment, SWT.CHECK);
    widgetFactory.createLabel(mainComposite, "");

    final Composite radioComposite = widgetFactory.createComposite(mainComposite);
    radioComposite.setLayoutData(
        GridDataFactory.fillDefaults()
            .align(SWT.FILL, SWT.CENTER)
            .grab(true, false)
            .span(3, 1)
            .create());
    radioComposite.setLayout(
        GridLayoutFactory.fillDefaults().numColumns(col).margins(0, 0).create());

    FileWidgetInputType initialInputType = createUseDocumentButton(widgetFactory, radioComposite);

    // createURLButton(widgetFactory, radioComposite);

    createUseResourceButton(radioComposite);

    initialValueSection =
        widgetFactory.createSection(mainComposite, Section.NO_TITLE | Section.CLIENT_INDENT);
    initialValueSection.setLayout(
        GridLayoutFactory.fillDefaults().numColumns(1).margins(0, 0).create());
    initialValueSection.setLayoutData(
        GridDataFactory.fillDefaults().grab(true, true).span(3, 1).create());

    if (initialInputType == FileWidgetInputType.DOCUMENT) {
      initialValueSection.setClient(
          createInputExpressionComposite(initialValueSection, widgetFactory));
      /*}else if(initialInputType == FileWidgetInputType.URL){
      initialValueSection.setClient(createInputExpressionComposite(initialValueSection, widgetFactory));*/
    } else if (initialInputType == FileWidgetInputType.RESOURCE) {
      if (element.isDuplicate()) {
        initialValueSection.setClient(
            createMultipleResourceComposite(initialValueSection, widgetFactory));
      } else {
        initialValueSection.setClient(createResourceComposite(initialValueSection, widgetFactory));
      }
    }
    bindFields();

    if (initialInputType == FileWidgetInputType.DOCUMENT) {
      useDocumentButton.setSelection(true);
      useDocumentButton.notifyListeners(SWT.Selection, new Event());

      /*}else if(initialInputType == FileWidgetInputType.URL){
      useURLButton.setSelection(true);*/
    } else {
      useResourceButton.setSelection(true);
      useResourceButton.notifyListeners(SWT.Selection, new Event());
    }
  }
  public static void removeMessageFlow(
      TransactionalEditingDomain editingDomain,
      Message event,
      ThrowMessageEvent source,
      DiagramEditPart dep) {
    EditPart ep = findEditPart(dep, source);
    CompositeCommand command = new CompositeCommand("Remove MessageFlows");

    for (Object connection : ((AbstractGraphicalEditPart) ep).getSourceConnections()) {
      if (connection instanceof MessageFlowEditPart) {
        MessageFlowEditPart connectionPart = (MessageFlowEditPart) connection;
        MessageFlow flow = (MessageFlow) connectionPart.resolveSemanticElement();
        if (flow.getTarget().getEvent() == null
            || flow.getTarget().getEvent().equals(event.getName())) {
          List<Message> events = new ArrayList<Message>();
          ModelHelper.findAllEvents(source, events);
          for (Message ev : events) {
            if (ev.eContainer().equals(source) && !ev.equals(event)) {
              if (ev.getTargetProcessExpression() != null
                  && event.getTargetProcessExpression() != null
                  && ev.getTargetProcessExpression()
                      .getContent()
                      .equals(event.getTargetProcessExpression().getContent())
                  && ev.getTargetElementExpression() != null
                  && ev.getTargetElementExpression().getContent() != null
                  && event.getTargetElementExpression() != null
                  && ev.getTargetElementExpression()
                      .getContent()
                      .equals(event.getTargetElementExpression().getContent())) {
                SetCommand setCommand =
                    new SetCommand(
                        editingDomain,
                        ev,
                        ProcessPackage.Literals.MESSAGE__TARGET_PROCESS_EXPRESSION,
                        null);
                editingDomain.getCommandStack().execute(setCommand);
                setCommand =
                    new SetCommand(
                        editingDomain,
                        ev,
                        ProcessPackage.Literals.MESSAGE__TARGET_ELEMENT_EXPRESSION,
                        null);
                editingDomain.getCommandStack().execute(setCommand);
              }
            }
          }
          SetCommand c =
              new SetCommand(
                  editingDomain,
                  flow.getTarget(),
                  ProcessPackage.Literals.ABSTRACT_CATCH_MESSAGE_EVENT__EVENT,
                  null);
          editingDomain.getCommandStack().execute(c);
          command.add(new DeleteCommand(editingDomain, connectionPart.getPrimaryView()));
          DestroyElementRequest req =
              new DestroyElementRequest(
                  editingDomain, connectionPart.resolveSemanticElement(), false);
          DestroyElementCommand rmComd = new DestroyElementCommand(req);
          command.add(rmComd);
        }
      }
    }
    dep.getDiagramEditDomain()
        .getDiagramCommandStack()
        .execute(new ICommandProxy(command.reduce()));
    dep.getDiagramEditDomain().getDiagramCommandStack().flush();
    dep.refresh();
  }
示例#17
0
  /* (non-Javadoc)
   * @see org.eclipse.jface.wizard.Wizard#performFinish()
   */
  @Override
  public boolean performFinish() {
    final TransactionalEditingDomain editingDomain = TransactionUtil.getEditingDomain(container);
    Data workingCopy = page.getWorkingCopy();
    setDatasourceId(workingCopy, dataContainmentFeature);
    if (editMode) {
      AbstractProcess process = ModelHelper.getParentProcess(container);
      CompoundCommand cc = new CompoundCommand();
      final RefactorDataOperation op =
          new RefactorDataOperation(BonitaGroovyRefactoringAction.REFACTOR_OPERATION);
      op.setCompoundCommand(cc);
      op.setEditingDomain(editingDomain);
      op.setContainer(process);
      op.setNewData(workingCopy);
      op.setOldData(originalData);
      op.updateReferencesInScripts();
      final boolean switchingDataeClass = !originalData.eClass().equals(workingCopy.eClass());
      op.setUpdateDataReferences(switchingDataeClass);
      if (op.isCanExecute()) {
        try {

          getContainer().run(true, false, op);

        } catch (InvocationTargetException e) {
          BonitaStudioLog.error(e);
        } catch (InterruptedException e) {
          BonitaStudioLog.error(e);
        }

        if (switchingDataeClass) {
          List<?> dataList = (List<?>) container.eGet(dataContainmentFeature);
          int index = dataList.indexOf(originalData);
          cc.append(
              RemoveCommand.create(editingDomain, container, dataContainmentFeature, originalData));
          cc.append(
              AddCommand.create(
                  editingDomain, container, dataContainmentFeature, workingCopy, index));
        } else {
          for (EStructuralFeature feature : originalData.eClass().getEAllStructuralFeatures()) {
            cc.append(
                SetCommand.create(editingDomain, originalData, feature, workingCopy.eGet(feature)));
          }
        }

        editingDomain.getCommandStack().execute(cc);
      } else {
        cc.dispose();
      }
    } else {
      editingDomain
          .getCommandStack()
          .execute(
              AddCommand.create(editingDomain, container, dataContainmentFeature, workingCopy));
    }
    try {
      RepositoryManager.getInstance()
          .getCurrentRepository()
          .getProject()
          .build(
              IncrementalProjectBuilder.FULL_BUILD,
              XtextProjectHelper.BUILDER_ID,
              Collections.EMPTY_MAP,
              null);
    } catch (CoreException e) {
      BonitaStudioLog.error(e, DataPlugin.PLUGIN_ID);
    }

    return true;
  }