@Override
  protected void setValue(Resource value) {
    if (value == null) {
      _filenameField.setFilename("");
      _otherPathTextField.setText("");
      return;
    }

    if (value instanceof FileResource) {
      _resourceTypeComboBox.setSelectedItem("file");
      File existingFile = _filenameField.getFile();
      File newFile = ((FileResource) value).getFile();
      if (existingFile != null
          && existingFile.getAbsoluteFile().equals(newFile.getAbsoluteFile())) {
        return;
      }
      _filenameField.setFile(newFile);
    } else if (value instanceof UrlResource) {
      _resourceTypeComboBox.setSelectedItem("url");
      final String url = ((UrlResource) value).getUri().toString();
      _otherPathTextField.setText(url);
    } else if (value instanceof ClasspathResource) {
      _resourceTypeComboBox.setSelectedItem("classpath");
      final String resourcePath = ((ClasspathResource) value).getResourcePath();
      _otherPathTextField.setText(resourcePath);
    } else if (value instanceof VfsResource) {
      _resourceTypeComboBox.setSelectedItem("vfs");
      final String path = ((VfsResource) value).getFileObject().getName().getURI();
      _otherPathTextField.setText(path);
    } else {
      throw new UnsupportedOperationException("Unsupported resource type: " + value);
    }
  }
  @Override
  public Resource getValue() {
    if (_immutableValue != null) {
      return _immutableValue;
    }

    String path;
    String resourceType = _resourceTypeComboBox.getSelectedItem();
    if ("file".equals(resourceType)) {
      path = _filenameField.getFilename();
    } else {
      path = _otherPathTextField.getText();
    }

    if (StringUtils.isNullOrEmpty(path)) {
      return null;
    }

    final String resourceString = resourceType + "://" + path;
    try {
      Resource resource = getResourceConverter().fromString(Resource.class, resourceString);
      return resource;
    } catch (Exception e) {
      // sometimes an exception can occur because the path is not valid (a
      // URL with a wrong pattern or so).
      if (logger.isDebugEnabled()) {
        logger.debug("Could not create resource from string: " + resourceString, e);
      }
      return null;
    }
  }
  @Inject
  public SingleResourcePropertyWidget(
      ConfiguredPropertyDescriptor propertyDescriptor,
      AbstractBeanJobBuilder<?, ?, ?> beanJobBuilder,
      UserPreferences userPreferences) {
    super(beanJobBuilder, propertyDescriptor);
    _userPreferences = userPreferences;

    boolean openFileDialog = true;
    String[] extensions = null;

    FileProperty fileProperty = propertyDescriptor.getAnnotation(FileProperty.class);
    if (fileProperty != null) {
      openFileDialog = fileProperty.accessMode() == FileAccessMode.OPEN;

      extensions = fileProperty.extension();
    }

    _resourceTypeComboBox =
        new DCComboBox<String>(new String[] {"file", "url", "classpath", "vfs"});
    _filenameField =
        new FilenameTextField(_userPreferences.getConfiguredFileDirectory(), openFileDialog);
    _otherPathTextField = WidgetFactory.createTextField();

    if (extensions != null && extensions.length > 0) {
      List<FileFilter> filters = new ArrayList<FileFilter>(extensions.length);
      for (String extension : extensions) {
        String extensionWithDot;
        if (extension.startsWith(".")) {
          extensionWithDot = extension;
        } else {
          extensionWithDot = "." + extension;
        }
        FileFilter filter =
            new ExtensionFilter(extension.toUpperCase() + " file", extensionWithDot);
        filters.add(filter);
        _filenameField.addChoosableFileFilter(filter);
      }
      if (filters.size() == 1) {
        _filenameField.setSelectedFileFilter(filters.get(0));
      } else {
        FileFilter filter =
            FileFilters.combined(
                "All suggested file formats", filters.toArray(new FileFilter[filters.size()]));
        _filenameField.setSelectedFileFilter(filter);
      }
    } else {
      _filenameField.setSelectedFileFilter(FileFilters.ALL);
    }

    final Resource currentValue = getCurrentValue();
    if (currentValue == null) {
      _otherPathTextField.setVisible(false);
      _immutableValue = null;
    } else if (currentValue instanceof FileResource) {
      _otherPathTextField.setVisible(false);
      _filenameField.setFile(((FileResource) currentValue).getFile());
      _immutableValue = null;
    } else if (currentValue instanceof UrlResource
        || currentValue instanceof VfsResource
        || currentValue instanceof ClasspathResource) {
      _filenameField.setVisible(false);
      _immutableValue = null;
    } else {
      _filenameField.setVisible(false);
      _immutableValue = currentValue;
    }

    if (_immutableValue == null) {
      _filenameField
          .getTextField()
          .getDocument()
          .addDocumentListener(
              new DCDocumentListener() {
                @Override
                protected void onChange(DocumentEvent e) {
                  fireValueChanged();
                }
              });

      _filenameField.addFileSelectionListener(
          new FileSelectionListener() {
            @Override
            public void onSelected(FilenameTextField filenameTextField, File file) {
              File dir = file.getParentFile();
              _userPreferences.setConfiguredFileDirectory(dir);
              fireValueChanged();
            }
          });

      _otherPathTextField
          .getDocument()
          .addDocumentListener(
              new DCDocumentListener() {
                @Override
                protected void onChange(DocumentEvent event) {
                  fireValueChanged();
                }
              });
      _resourceTypeComboBox.addListener(
          new Listener<String>() {
            @Override
            public void onItemSelected(String item) {
              boolean isFileMode = "file".equals(item);
              _filenameField.setVisible(isFileMode);
              _otherPathTextField.setVisible(!isFileMode);

              fireValueChanged();
            }
          });

      final DCPanel panel =
          DCPanel.flow(
              Alignment.LEFT, 0, 0, _resourceTypeComboBox, _filenameField, _otherPathTextField);
      add(panel);
    } else {
      add(DCLabel.dark("- Resource: " + _immutableValue.getName() + " -"));
    }
  }