
net.anwiba.spatial.swing.ckan.search.FormatTableFactory Maven / Gradle / Ivy
/*
* #%L
* *
* %%
* Copyright (C) 2007 - 2018 Andreas W. Bartels ([email protected])
* %%
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation, either version 2.1 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Lesser Public License for more details.
*
* You should have received a copy of the GNU General Lesser Public
* License along with this program. If not, see
* .
* #L%
*/
package net.anwiba.spatial.swing.ckan.search;
import java.awt.Component;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.io.IOException;
import java.io.InterruptedIOException;
import java.net.SocketException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import net.anwiba.commons.datasource.connection.IHttpConnectionDescription;
import net.anwiba.commons.http.IObjectRequestExecutor;
import net.anwiba.commons.http.IObjectRequestExecutorBuilderFactory;
import net.anwiba.commons.http.IRequest;
import net.anwiba.commons.http.IResultProducer;
import net.anwiba.commons.lang.exception.CanceledException;
import net.anwiba.commons.lang.functional.IBlock;
import net.anwiba.commons.lang.optional.Optional;
import net.anwiba.commons.lang.stream.Streams;
import net.anwiba.commons.logging.ILevel;
import net.anwiba.commons.model.BooleanModel;
import net.anwiba.commons.model.IBooleanModel;
import net.anwiba.commons.model.IObjectModel;
import net.anwiba.commons.preferences.IPreferences;
import net.anwiba.commons.swing.action.ActionProcedurBuilder;
import net.anwiba.commons.swing.action.ConfigurableActionBuilder;
import net.anwiba.commons.swing.action.IActionProcedure;
import net.anwiba.commons.swing.dialog.ConfigurableDialogLauncher;
import net.anwiba.commons.swing.dialog.DialogResult;
import net.anwiba.commons.swing.dialog.IDialogResult;
import net.anwiba.commons.swing.dialog.MessageDialogLauncher;
import net.anwiba.commons.swing.dialog.progress.ProgressDialogLauncher;
import net.anwiba.commons.swing.table.IObjectTableModel;
import net.anwiba.commons.swing.table.ObjectListTable;
import net.anwiba.commons.swing.table.ObjectTableBuilder;
import net.anwiba.commons.swing.utilities.GuiUtilities;
import net.anwiba.commons.thread.cancel.ICanceler;
import net.anwiba.commons.thread.progress.IProgressMonitor;
import net.anwiba.commons.thread.progress.IProgressTask;
import net.anwiba.commons.utilities.string.StringUtilities;
import net.anwiba.spatial.ckan.json.schema.v1_0.StringListResultResponse;
import net.anwiba.spatial.ckan.marshaller.CkanJsonResponseUnmarshallerFactory;
import net.anwiba.spatial.ckan.request.ResourceFormatRequestBuilder;
import net.anwiba.spatial.ckan.request.ResourceFormatRequestBuilder.ResourceFormatListRequestBuilder;
import net.anwiba.spatial.swing.ckan.search.message.Messages;
public class FormatTableFactory {
private static net.anwiba.commons.logging.ILogger logger = net.anwiba.commons.logging.Logging
.getLogger(FormatTableFactory.class);
private final IObjectRequestExecutorBuilderFactory requestExecutorBuilderFactory;
public FormatTableFactory(final IObjectRequestExecutorBuilderFactory requestExecutorBuilderFactory) {
this.requestExecutorBuilderFactory = requestExecutorBuilderFactory;
}
public ObjectListTable create(
final IPreferences preferences,
final IHttpConnectionDescription description,
final List formatStrings) {
final List formats = new ArrayList<>();
return new ObjectTableBuilder()
.setValues(formatStrings)
.addSortableStringColumn(Messages.name, value -> value, 10)
.addTextFieldActionFactory(
(tableModel, selectionIndicesProvider, selectionModel, sortStateModel, model, clearblock) -> {
final IBooleanModel enabledModel = new BooleanModel(false);
model.addChangeListener(() -> enabledModel.set(!StringUtilities.isNullOrTrimmedEmpty(model.get())));
return new ConfigurableActionBuilder()
.setIcon(net.anwiba.commons.swing.icons.GuiIcons.ADVANCED_SEARCH_ICON)
.setEnabledDistributor(enabledModel)
.setProcedure(
createSearchFormatActionProcedure(
description,
preferences,
new ArrayList<>(),
tableModel,
clearblock,
model))
.build();
})
.addTextFieldActionFactory(
(tableModel, selectionIndicesProvider, selectionModel, sortStateModel, model, clearblock) -> {
final IBooleanModel enabledModel = new BooleanModel(false);
model.addChangeListener(() -> enabledModel.set(!StringUtilities.isNullOrTrimmedEmpty(model.get())));
return new ConfigurableActionBuilder()
.setIcon(net.anwiba.commons.swing.icons.gnome.contrast.high.ContrastHightIcons.ADD)
.setEnabledDistributor(enabledModel)
.setProcedure(component -> {
final String value = model.get();
clearblock.execute();
final List values = new ArrayList<>();
for (final String token : StringUtilities.trimedTokens(value, ',')) {
Streams
.of(tableModel.values()) //
.first(v -> token.equalsIgnoreCase(v))
.or(() -> values.add(token));
}
tableModel.add(values);
})
.build();
})
.addActionFactory(
(tableModel, selectionIndicesProvider, selectionModel, sortStateModel) -> new ConfigurableActionBuilder()
.setIcon(net.anwiba.commons.swing.icons.GuiIcons.EDIT_ICON)
.setProcedure(createSelectFormatActionProcedure(description, preferences, formats, tableModel))
.build())
.addRemoveObjectsAction()
.addActionFactory((tableModel, selectionIndicesProvider, selectionModel, sortStateModel) -> {
final IBooleanModel enabledModel = new BooleanModel(!tableModel.isEmpty());
tableModel.addTableModelListener(e -> enabledModel.set(!tableModel.isEmpty()));
return new ConfigurableActionBuilder()
.setIcon(net.anwiba.commons.swing.icons.GuiIcons.EDIT_CLEAR_LIST)
.setEnabledDistributor(enabledModel)
.setProcedure(component -> tableModel.removeAll())
.build();
})
.setTextFieldKeyListenerFactory(
(tableModel, selectionIndicesProvider, selectionModel, model, clearBlock) -> new KeyAdapter() {
@Override
public void keyTyped(final KeyEvent e) {
if (e.getKeyChar() == '\n') {
final String value = model.get();
if (StringUtilities.isNullOrTrimmedEmpty(value)) {
return;
}
clearBlock.execute();
final List values = new ArrayList<>();
for (final String token : StringUtilities.trimedTokens(value, ',')) {
Streams
.of(tableModel.values()) //
.first(v -> token.equalsIgnoreCase(v))
.or(() -> values.add(token));
}
tableModel.add(values);
}
}
})
.build();
}
private IActionProcedure createSearchFormatActionProcedure(
final IHttpConnectionDescription description,
final IPreferences preferences,
final List formats,
final IObjectTableModel tableModel,
final IBlock clearblock,
final IObjectModel model) {
return new ActionProcedurBuilder, List>().setInitializer(parentComponent -> {
final String string = model.get();
clearblock.execute();
return getValues(parentComponent, description, formats, string);
}).setConsumer((parentComponent, values) -> {
if (values == null) {
return;
}
final List selections = new ArrayList<>();
final IDialogResult result = new ConfigurableDialogLauncher()
.setPreferences(preferences.node("formats")) //$NON-NLS-1$
.setTitle(Messages.formats)
.enableCloseOnEscape()
.setContentPaneFactory((o, p) -> new SelectTableContentPane<>(selections, tableModel, values, v -> v))
.setCancleOkButtonDialog()
.launch(parentComponent);
if (result != DialogResult.OK) {
return;
}
final List filtered = Streams
.of(selections)
.filter(f -> !StringUtilities.isNullOrTrimmedEmpty(f))
.filter(f -> !Streams.of(tableModel.values()).first(v -> f.equalsIgnoreCase(v)).isAccepted())
.asList();
GuiUtilities.invokeLater(() -> tableModel.add(filtered));
}).build();
}
private IActionProcedure createSelectFormatActionProcedure(
final IHttpConnectionDescription description,
final IPreferences preferences,
final List formats,
final IObjectTableModel tableModel) {
return new ActionProcedurBuilder, List>().setInitializer(parentComponent -> {
final List values = getValues(parentComponent, description, formats, null);
if (formats.isEmpty() && values != null && !values.isEmpty()) {
formats.addAll(values);
}
return values;
}).setConsumer((parentComponent, value) -> {
if (value == null) {
return;
}
final List selections = new ArrayList<>();
final IDialogResult result = new ConfigurableDialogLauncher()
.setPreferences(preferences.node("formats")) //$NON-NLS-1$
.setTitle(Messages.formats)
.enableCloseOnEscape()
.setContentPaneFactory((o, p) -> new SelectTableContentPane<>(selections, tableModel, value, v -> v))
.setCancleOkButtonDialog()
.launch(parentComponent);
if (result != DialogResult.OK) {
return;
}
tableModel.set(selections);
}).build();
}
private List getValues(
final Component parentComponent,
final IHttpConnectionDescription description,
final List values,
final String value) {
try {
return new ProgressDialogLauncher<>(new IProgressTask, IOException>() {
@Override
public List run(final IProgressMonitor progressMonitor, final ICanceler canceler)
throws CanceledException,
IOException {
final List result = new ArrayList<>();
if (values.isEmpty()) {
getValues(canceler, description, value)
.stream()
.filter(s -> !StringUtilities.isNullOrTrimmedEmpty(s))
.sorted()
.forEachOrdered(s -> result.add(s));
return result;
}
if (value != null) {
return Streams.of(values).filter(f -> f.equalsIgnoreCase(value)).asList();
}
return values;
}
}).launch(parentComponent);
} catch (final CanceledException exception1) {
return null;
} catch (final IOException exception) {
logger.log(ILevel.DEBUG, Messages.format_query_faild, exception);
new MessageDialogLauncher()
.error()
.title(Messages.formats)
.text(Messages.format_query_faild)
.description(exception.getMessage())
.throwable(exception)
.launch(parentComponent);
return null;
}
}
private List getValues(
final ICanceler canceler,
final IHttpConnectionDescription description,
final String string)
throws CanceledException,
IOException {
final IResultProducer responseProducer = (
c,
statusCode,
statusMessage,
contentType,
contentEncoding,
inputStream) -> new CkanJsonResponseUnmarshallerFactory().create(StringListResultResponse.class).unmarshal(
inputStream);
final ResourceFormatListRequestBuilder builder = ResourceFormatRequestBuilder
.list(description.getUrl())
.authentication(description.getUserName(), description.getPassword())
.setLimit(200);
Optional.of(string).consume(s -> builder.setSearchStringPart(string));
final IRequest request = builder.build();
try (final IObjectRequestExecutor executor = this.requestExecutorBuilderFactory
. create()
.setResultProducer(responseProducer)
.addResultProducer(
(statusCode, contentType) -> new HashSet<>(Arrays.asList(409, 400, 500)).contains(statusCode)
&& contentType != null
&& contentType.startsWith("application/json"), //$NON-NLS-1$
responseProducer)
.build()) {
final StringListResultResponse response = executor.execute(canceler, request);
return response.isSuccess() ? Arrays.asList(response.getResult()) : Collections.emptyList();
} catch (SocketException | InterruptedIOException exception) {
if (canceler.isCanceled()) {
throw new CanceledException();
}
throw exception;
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy