@Test
  public void testGlobalSchemeConfig() throws Exception {
    final TerminalClause testClause = new TerminalClauseImpl("one", Operator.LIKE, "fine");
    final ClauseContext context3 = createContextForProjects(64);

    final FieldConfigScheme scheme = mock(FieldConfigScheme.class);

    when(customField.getConfigurationSchemes()).thenReturn(Arrays.asList(scheme, scheme, scheme));
    when(fieldConfigSchemeClauseContextUtil.getContextForConfigScheme(theUser, scheme))
        .thenReturn(context3);
    when(scheme.isGlobal()).thenReturn(false, true);

    final CascadingSelectCustomFieldClauseContextFactory factory =
        new CascadingSelectCustomFieldClauseContextFactory(
            customField,
            contextSetUtil,
            jqlSelectOptionsUtil,
            fieldConfigSchemeClauseContextUtil,
            jqlOperandResolver,
            jqlCascadingSelectLiteralUtil,
            operatorUsageValidator);

    assertEquals(
        ClauseContextImpl.createGlobalClauseContext(),
        factory.getClauseContext(theUser, testClause));
  }
  @Test
  public void testNegativeQueryWithPositiveAndNegativeOptions() throws Exception {
    final TerminalClause testClause = new TerminalClauseImpl("one", Operator.NOT_EQUALS, "fine");
    final MockOption option1 = new MockOption(null, null, null, null, null, 25L);
    final MockOption option2 = new MockOption(null, null, null, null, null, 26L);
    final MockOption option2child2 = new MockOption(option2, null, null, null, null, 28L);
    final MockOption option2child1 = new MockOption(option2, null, null, null, null, 27L);
    option2.setChildOptions(Arrays.asList(option2child1, option2child2));

    final ClauseContext context1 = createContextForProjects(1, 2);
    final ClauseContext context2 = createContextForProjects(3);
    final ClauseContext context3 = createContextForProjects(3);

    final FieldConfigScheme scheme = mock(FieldConfigScheme.class);
    when(scheme.isGlobal()).thenReturn(false);

    when(customField.getConfigurationSchemes()).thenReturn(Arrays.asList(scheme, scheme));

    when(fieldConfigSchemeClauseContextUtil.getContextForConfigScheme(theUser, scheme))
        .thenReturn(context1, context2);

    // The second scheme should not be included because it only has options that we are to exclude.
    when(jqlSelectOptionsUtil.getOptionsForScheme(scheme))
        .thenReturn(Arrays.<Option>asList(option1, option2))
        .thenReturn(Arrays.<Option>asList(option2, option2child1, option2child2));

    when(contextSetUtil.union(CollectionBuilder.newBuilder(context1, context2).asSet()))
        .thenReturn(context3);

    final CascadingSelectCustomFieldClauseContextFactory factory =
        new CascadingSelectCustomFieldClauseContextFactory(
            customField,
            contextSetUtil,
            jqlSelectOptionsUtil,
            fieldConfigSchemeClauseContextUtil,
            jqlOperandResolver,
            jqlCascadingSelectLiteralUtil,
            operatorUsageValidator) {
          @Override
          void fillOptions(
              final User user,
              final TerminalClause clause,
              final Set<Option> positiveOption,
              final Set<Option> negativeOption) {

            assertEquals(theUser, user);
            assertEquals(testClause, clause);

            positiveOption.add(option2);
            negativeOption.add(option2child1);
          }
        };

    assertEquals(context3, factory.getClauseContext(theUser, testClause));
  }
  @Override
  public String doDefault() throws Exception {
    if (isFieldLocked()) {
      return "locked";
    }

    // Set up the context so the view can see it nicely.
    final FieldConfigScheme configScheme = getConfig();
    setGlobal(isGlobalAvailable());
    if (configScheme != null) {
      setName(configScheme.getName());
      setDescription(configScheme.getDescription());

      // Check if this is still editable in "basic" mode
      if (configScheme.isBasicMode()) {
        setBasicMode(true);
        setGlobal(configScheme.isAllProjects());

        final Set issueTypesList = configScheme.getAssociatedIssueTypes();
        setIssuetypes(GenericValueUtils.transformToStrings(issueTypesList, "id"));

        final List projectCategoriesList = configScheme.getAssociatedProjectCategories();
        setProjectCategories(GenericValueUtils.transformToLongIds(projectCategoriesList));

        final List projectsList = configScheme.getAssociatedProjects();
        setProjects(GenericValueUtils.transformToLongIds(projectsList));

        // Set the config
        final MultiMap configMap = configScheme.getConfigsByConfig();
        if (configMap == null) {
          fieldConfigIds = new Long[0];
        } else {
          final Set entries = configScheme.getConfigsByConfig().keySet();
          fieldConfigIds = new Long[entries.size()];
          int i = 0;
          for (final Object entry : entries) {
            final FieldConfig config = (FieldConfig) entry;
            fieldConfigIds[i] = config.getId();
            i++;
          }
        }

      } else {
        // Complex mode
        setBasicMode(false);
        // @TODO
      }
    }

    return super.doDefault();
  }
 public Builder(final FieldConfigScheme scheme) {
   if (scheme != null) {
     id = scheme.getId();
     name = scheme.getName();
     description = scheme.getDescription();
     configs = scheme.getConfigs();
     if (scheme instanceof FieldConfigSchemeImpl) {
       final FieldConfigSchemeImpl fieldConfigSchemeImpl = (FieldConfigSchemeImpl) scheme;
       configContextPersister = fieldConfigSchemeImpl.getFieldConfigContextPersister();
       fieldId = fieldConfigSchemeImpl.getFieldId();
     } else {
       final ConfigurableField field = scheme.getField();
       fieldId = (field != null) ? field.getId() : null;
     }
   }
 }
  @Test
  public void testNegativeQueryWithNoOptions() throws Exception {
    final TerminalClause testClause = new TerminalClauseImpl("one", Operator.NOT_IN, "fine");
    final MockOption option2 = new MockOption(null, null, null, null, null, 26L);
    final MockOption option2child2 = new MockOption(option2, null, null, null, null, 28L);
    final MockOption option2child1 = new MockOption(option2, null, null, null, null, 27L);
    option2.setChildOptions(Arrays.asList(option2child1, option2child2));

    final ClauseContext context2 = createContextForProjects(3);
    final ClauseContext context3 = createContextForProjects(64);
    final ClauseContext context4 = createContextForProjects(34938);

    final FieldConfigScheme scheme = mock(FieldConfigScheme.class);
    when(scheme.isGlobal()).thenReturn(false);

    when(customField.getConfigurationSchemes()).thenReturn(Arrays.asList(scheme, scheme));

    when(fieldConfigSchemeClauseContextUtil.getContextForConfigScheme(theUser, scheme))
        .thenReturn(context3, context2);
    when(contextSetUtil.union(CollectionBuilder.newBuilder(context2, context3).asSet()))
        .thenReturn(context4);

    final CascadingSelectCustomFieldClauseContextFactory factory =
        new CascadingSelectCustomFieldClauseContextFactory(
            customField,
            contextSetUtil,
            jqlSelectOptionsUtil,
            fieldConfigSchemeClauseContextUtil,
            jqlOperandResolver,
            jqlCascadingSelectLiteralUtil,
            operatorUsageValidator) {
          @Override
          void fillOptions(
              final User user,
              final TerminalClause clause,
              final Set<Option> positiveOption,
              final Set<Option> negativeOption) {
            assertEquals(theUser, user);
            assertEquals(testClause, clause);
          }
        };

    assertEquals(context4, factory.getClauseContext(theUser, testClause));
  }
  public Collection getAllProjects() throws Exception {
    Collection availableProjects = Collections.EMPTY_LIST;

    final Collection projects = projectManager.getProjects();

    if (projects != null) {
      availableProjects = new ArrayList(projects);
      availableProjects =
          CollectionUtils.subtract(availableProjects, getCustomField().getAssociatedProjects());
      final FieldConfigScheme fieldConfigScheme = getFieldConfigScheme();
      if (fieldConfigScheme != null) {
        final List currentlySlectedProjects = fieldConfigScheme.getAssociatedProjects();
        if (currentlySlectedProjects != null) {
          availableProjects.addAll(currentlySlectedProjects);
        }
      }
    }

    return availableProjects;
  }
  @RequiresXsrfCheck
  public String doRemove() throws Exception {
    if (isFieldLocked()) {
      return "locked";
    }

    final FieldConfigScheme configScheme = getConfig();

    if (customFieldContextConfigHelper.doesRemovingSchemeFromCustomFieldAffectIssues(
        getLoggedInUser(), getCustomField(), configScheme)) {
      reindexMessageManager.pushMessage(
          getLoggedInUser(), "admin.notifications.task.custom.fields");
    }

    fieldConfigSchemeManager.removeFieldConfigScheme(configScheme.getId());

    ComponentAccessor.getFieldManager().refresh();
    customFieldManager.refreshConfigurationSchemes(getCustomFieldId());
    return redirectToView();
  }
  @Test
  public void testPositiveQueryWithNoPositive() throws Exception {
    final TerminalClause testClause = new TerminalClauseImpl("one", Operator.EQUALS, "fine");
    final MockOption option1 = new MockOption(null, null, null, null, null, 25L);
    final MockOption option2 = new MockOption(null, null, null, null, null, 26L);
    final MockOption option2child2 = new MockOption(option2, null, null, null, null, 28L);
    final MockOption option2child1 = new MockOption(option2, null, null, null, null, 27L);
    option2.setChildOptions(Arrays.asList(option2child1, option2child2));

    final FieldConfigScheme scheme = mock(FieldConfigScheme.class);

    when(customField.getConfigurationSchemes()).thenReturn(Arrays.asList(scheme, scheme));
    when(scheme.isGlobal()).thenReturn(true);

    final CascadingSelectCustomFieldClauseContextFactory factory =
        new CascadingSelectCustomFieldClauseContextFactory(
            customField,
            contextSetUtil,
            jqlSelectOptionsUtil,
            fieldConfigSchemeClauseContextUtil,
            jqlOperandResolver,
            jqlCascadingSelectLiteralUtil,
            operatorUsageValidator) {
          @Override
          void fillOptions(
              final User user,
              final TerminalClause clause,
              final Set<Option> positiveOption,
              final Set<Option> negativeOption) {
            assertEquals(theUser, user);
            assertEquals(testClause, clause);

            negativeOption.add(option2);
            negativeOption.add(option1);
          }
        };

    assertEquals(
        ClauseContextImpl.createGlobalClauseContext(),
        factory.getClauseContext(theUser, testClause));
  }
  @Test
  public void testPositiveQueryWithPositiveAndEmpty() throws Exception {
    final TerminalClause testClause = new TerminalClauseImpl("one", Operator.EQUALS, "fine");
    final ClauseContext context1 = createContextForProjects(1, 56);

    final FieldConfigScheme scheme = mock(FieldConfigScheme.class);

    when(customField.getConfigurationSchemes()).thenReturn(Arrays.asList(scheme, scheme));
    when(scheme.isGlobal()).thenReturn(false, true);
    when(fieldConfigSchemeClauseContextUtil.getContextForConfigScheme(theUser, scheme))
        .thenReturn(context1);

    final CascadingSelectCustomFieldClauseContextFactory factory =
        new CascadingSelectCustomFieldClauseContextFactory(
            customField,
            contextSetUtil,
            jqlSelectOptionsUtil,
            fieldConfigSchemeClauseContextUtil,
            jqlOperandResolver,
            jqlCascadingSelectLiteralUtil,
            operatorUsageValidator) {
          @Override
          void fillOptions(
              final User user,
              final TerminalClause clause,
              final Set<Option> positiveOption,
              final Set<Option> negativeOption) {
            assertEquals(theUser, user);
            assertEquals(testClause, clause);

            positiveOption.add(null);
          }
        };

    assertEquals(
        ClauseContextImpl.createGlobalClauseContext(),
        factory.getClauseContext(theUser, testClause));
  }
  @Override
  @RequiresXsrfCheck
  protected String doExecute() throws Exception {
    if (isFieldLocked()) {
      return "locked";
    }

    FieldConfigScheme configScheme =
        new FieldConfigScheme.Builder(getConfig())
            .setName(getName())
            .setDescription(getDescription())
            .toFieldConfigScheme();

    if (isBasicMode()) {
      // Add the contexts
      final List<JiraContextNode> contexts =
          CustomFieldUtils.buildJiraIssueContexts(
              isGlobal(), getProjectCategories(), getProjects(), treeManager);

      // Add the issue types
      final List<GenericValue> issueTypes =
          CustomFieldUtils.buildIssueTypes(constantsManager, getIssuetypes());

      boolean messageRequired;
      if (configScheme.getId() == null) {
        messageRequired =
            customFieldContextConfigHelper.doesAddingContextToCustomFieldAffectIssues(
                getLoggedInUser(), getCustomField(), contexts, issueTypes, false);

        configScheme =
            fieldConfigSchemeManager.createFieldConfigScheme(
                configScheme, contexts, issueTypes, getCustomField());
      } else {
        // keep a handle on the old scheme (pre edit) projects and issue types
        messageRequired =
            customFieldContextConfigHelper.doesChangingContextAffectIssues(
                getLoggedInUser(),
                getCustomField(),
                configScheme,
                isGlobal(),
                contexts,
                issueTypes);

        // Update so keep the old config
        if (issueTypes != null) {
          // Since we know that there is only one config
          final Long configId = getFieldConfigIds()[0];
          final FieldConfig config = fieldConfigManager.getFieldConfig(configId);
          final Map<String, FieldConfig> configs =
              new HashMap<String, FieldConfig>(issueTypes.size());
          for (final GenericValue issueType : issueTypes) {
            final String issueTypeId =
                issueType == null
                    ? null
                    : issueType.getString(FieldConfigSchemePersisterImpl.ENTITY_ID);
            configs.put(issueTypeId, config);
          }
          configScheme =
              new FieldConfigScheme.Builder(configScheme).setConfigs(configs).toFieldConfigScheme();
        }
        configScheme =
            fieldConfigSchemeManager.updateFieldConfigScheme(
                configScheme, contexts, getCustomField());
      }

      if (messageRequired) {
        reindexMessageManager.pushMessage(
            getLoggedInUser(), "admin.notifications.task.custom.fields");
      }

      fieldConfigScheme = configScheme;
    } else {
      // @TODO advanced config
    }

    ComponentAccessor.getFieldManager().refresh();
    customFieldManager.refreshConfigurationSchemes(getCustomFieldId());

    return redirectToView();
  }