package be.billington.rob;
import ch.qos.logback.classic.Logger;
import ch.qos.logback.classic.LoggerContext;
import ch.qos.logback.classic.encoder.PatternLayoutEncoder;
import ch.qos.logback.core.ConsoleAppender;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import okio.*;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.layout.RowLayout;
import org.eclipse.swt.widgets.*;
import java.io.File;
import java.io.IOException;
import java.lang.reflect.Type;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class MainSWT {
private Shell shell;
private Text txtOwner, txtRepo, txtPrefix, txtBranch, txtConsole, txtFilePath, txtConfigPath;
private DateTime dateFrom, dateTo;
private Combo comboApi, profilesCombo;
private Logger logger;
private File configFile, profileFile;
private List<Profile> profiles;
private ExecutorService pool = Executors.newFixedThreadPool(4);
private Map<String, String> config = new HashMap<>();
public MainSWT(Display display) {
LoggerContext context = new LoggerContext();
logger = context.getLogger(MainSWT.class);
shell = new Shell(display);
shell.setText("Rob");
initConfig();
initProfiles();
initUI();
initUIProfiles(false);
initLogger(context);
shell.open();
while (!shell.isDisposed()) {
if (!display.readAndDispatch()) {
display.sleep();
}
}
}
private void initUIProfiles(boolean last) {
int pos = 0;
if (last){
pos = profiles.size() - 1;
}
if (profiles != null) {
profilesCombo.removeAll();
profiles.forEach((p) -> profilesCombo.add(p.getTitle()));
profilesCombo.select(pos);
}
bindProfile(pos);
}
private void initLogger(LoggerContext context) {
ConsoleAppender consoleAppender = new ConsoleAppender<>();
UIAppender uiAppender = new UIAppender((txt) -> Display.getDefault().asyncExec( () -> txtConsole.append(txt) ));
PatternLayoutEncoder pa = new PatternLayoutEncoder();
pa.setPattern("%r %5p %c [%t] - %m%n");
pa.setContext(context);
pa.start();
uiAppender.setContext(context);
uiAppender.start();
consoleAppender.setEncoder(pa);
consoleAppender.setContext(context);
consoleAppender.start();
logger.addAppender(uiAppender);
logger.addAppender(consoleAppender);
}
private void initConfig() {
configFile = new File("./rob.conf");
try {
if (!readConfig()) {
createConfig();
}
} catch (IOException e) {
logger.error("IOException: " + e.getMessage(), e);
}
}
private void initProfiles() {
profileFile = new File("./rob.profiles");
try {
Gson gson = new Gson();
Source source = Okio.source(profileFile);
BufferedSource profileGsonSource = Okio.buffer(source);
Type listType = new TypeToken<ArrayList<Profile>>() {}.getType();
profiles = gson.fromJson(profileGsonSource.readUtf8(), listType);
profileGsonSource.close();
source.close();
} catch (IOException e) {
logger.error("IOException: " + e.getMessage(), e);
}
}
private void writeConfig() throws IOException {
Sink sink = Okio.sink(configFile);
BufferedSink bufferedSink = Okio.buffer(sink);
this.config.forEach((k, v) -> {
try {
bufferedSink.writeUtf8(k + "=" + v + "\n");
} catch (IOException e) {
logger.error("IOException: " + e.getMessage(), e);
}
});
bufferedSink.close();
sink.close();
}
private boolean readConfig() throws IOException {
if (!configFile.exists()) {
return false;
}
boolean simpleCheckatLeastOneLine = false;
Source source = Okio.source(configFile);
BufferedSource bufferedSource = Okio.buffer(source);
String line = bufferedSource.readUtf8Line();
while (line != null) {
if (line.contains("=")) {
String[] values = line.split("=");
if (values.length > 1) {
this.config.put(values[0], values[1]);
}
}
line = bufferedSource.readUtf8Line();
simpleCheckatLeastOneLine = true;
}
bufferedSource.close();
source.close();
return simpleCheckatLeastOneLine;
}
private void createConfig() {
ConfigDialog configDialog = new ConfigDialog(shell, config);
config = configDialog.open();
try {
writeConfig();
} catch (IOException e) {
logger.error("IOException: " + e.getMessage(), e);
}
}
public void initUI() {
shell.setLayout(new FillLayout());
Composite inputContainer = new Composite(shell, SWT.BORDER);
inputContainer.setLayout(new RowLayout(SWT.VERTICAL));
ToolBar bar = new ToolBar (inputContainer, SWT.FLAT | SWT.BORDER);
initToolBar(bar);
profilesCombo = new Combo(inputContainer, SWT.PUSH);
profilesCombo.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
super.widgetSelected(e);
bindProfile(profilesCombo.getSelectionIndex());
}
});
//1st column
Composite container = new Composite(inputContainer, SWT.PUSH);
GridLayout layout = new GridLayout(2, false);
layout.marginWidth = 10;
container.setLayout(layout);
Label lblRepo = new Label(container, SWT.NONE);
lblRepo.setText("Repository name:");
txtRepo = new Text(container, SWT.BORDER);
txtRepo.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));
Label lblOwner = new Label(container, SWT.NONE);
GridData gd_lblNewLabel = new GridData(SWT.LEFT, SWT.CENTER, false, false, 1, 1);
gd_lblNewLabel.horizontalIndent = 1;
lblOwner.setLayoutData(gd_lblNewLabel);
lblOwner.setText("Owner:");
txtOwner = new Text(container, SWT.BORDER);
txtOwner.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));
Label lblApi = new Label(container, SWT.NONE);
lblApi.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));
lblApi.setText("API:");
comboApi = new Combo(container, SWT.PUSH);
comboApi.setItems(new String[]{Rob.API_BITBUCKET, Rob.API_GITHUB});
Label lblPrefix = new Label(container, SWT.NONE);
lblPrefix.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));
lblPrefix.setText("Jira Prefix:");
txtPrefix = new Text(container, SWT.BORDER);
txtPrefix.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));
Label lblBranch = new Label(container, SWT.NONE);
lblBranch.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));
lblBranch.setText("Branch:");
txtBranch = new Text(container, SWT.BORDER);
txtBranch.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));
Label lblFilePath = new Label(container, SWT.NONE);
lblFilePath.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));
lblFilePath.setText("File Path:");
Composite filePathComposite = new Composite(container, SWT.FLAT);
filePathComposite.setLayout(new RowLayout(SWT.HORIZONTAL));
txtFilePath = new Text(filePathComposite, SWT.BORDER);
Button fileChooser = new Button(filePathComposite, SWT.PUSH);
fileChooser.setText("Browse...");
fileChooser.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
super.widgetSelected(e);
FileDialog dialog = new FileDialog(shell);
String filePath = dialog.open();
if (filePath != null) {
txtFilePath.setText(filePath);
}
}
});
Label lblConfigPath = new Label(container, SWT.NONE);
lblConfigPath.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));
lblConfigPath.setText("Config Path:");
Composite configPathComposite = new Composite(container, SWT.FLAT);
configPathComposite.setLayout(new RowLayout(SWT.HORIZONTAL));
txtConfigPath = new Text(configPathComposite, SWT.BORDER);
Button configFileChooser = new Button(configPathComposite, SWT.PUSH);
configFileChooser.setText("Browse...");
configFileChooser.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
super.widgetSelected(e);
FileDialog dialog = new FileDialog(shell);
String filePath = dialog.open();
if (filePath != null) {
txtConfigPath.setText(filePath);
}
}
});
Label lblFromDate = new Label(container, SWT.NONE);
lblFromDate.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));
lblFromDate.setText("From date:");
dateFrom = new DateTime(container, SWT.BORDER | SWT.DATE | SWT.DROP_DOWN);
Label lblToDate = new Label(container, SWT.NONE);
lblToDate.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));
lblToDate.setText("To date:");
dateTo = new DateTime(container, SWT.BORDER | SWT.DATE | SWT.DROP_DOWN);
//2nd column
Composite rightContainer = new Composite(shell, SWT.BORDER);
rightContainer.setLayout(new FillLayout());
txtConsole = new Text(rightContainer, SWT.BORDER | SWT.H_SCROLL | SWT.V_SCROLL | SWT.MULTI);
txtConsole.setEditable(false);
}
private void initToolBar(ToolBar bar) {
ToolItem generate = new ToolItem(bar, SWT.PUSH);
generate.setText("Generate");
generate.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
robIt();
}
});
new ToolItem(bar, SWT.SEPARATOR);
ToolItem output = new ToolItem(bar, SWT.PUSH);
output.setText("Display output");
output.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
loadGeneratedFile();
}
});
new ToolItem(bar, SWT.SEPARATOR);
ToolItem settings = new ToolItem(bar, SWT.PUSH);
settings.setText("Settings");
settings.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
createConfig();
}
});
new ToolItem(bar, SWT.SEPARATOR);
ToolItem saveProfile = new ToolItem(bar, SWT.PUSH);
saveProfile.setText("Save/Add profile");
saveProfile.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
saveProfile();
}
});
new ToolItem(bar, SWT.SEPARATOR);
ToolItem removeProfile = new ToolItem(bar, SWT.PUSH);
removeProfile.setText("Remove current profile");
removeProfile.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
removeCurrentProfile();
}
});
new ToolItem(bar, SWT.SEPARATOR);
ToolItem quit = new ToolItem(bar, SWT.PUSH);
quit.setText("Quit");
quit.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
shell.getDisplay().dispose();
System.exit(0);
}
});
}
private void bindProfile(int pos) {
if (profiles == null || profiles.isEmpty()) {
comboApi.select(0);
txtOwner.setText("afrogleap");
txtRepo.setText("wecycle-android-recyclemanager");
txtPrefix.setText("WEC");
txtBranch.setText("development");
txtFilePath.setText("./target/changelog.txt");
} else {
Profile profile = profiles.get(pos);
if (profile.getApi().equalsIgnoreCase(Rob.API_BITBUCKET)){
comboApi.select(0);
} else {
comboApi.select(1);
}
txtOwner.setText(profile.getOwner());
txtRepo.setText(profile.getRepo());
txtPrefix.setText(profile.getPrefix());
txtBranch.setText(profile.getBranch());
txtFilePath.setText(profile.getFilePath());
if (profile.getFromDate() != null && !profile.getFromDate().isEmpty()) {
LocalDate date = LocalDate.parse(profile.getFromDate());
dateFrom.setDate(date.getYear(), date.getMonthValue() - 1, date.getDayOfMonth());
}
if (profile.getToDate() != null && !profile.getToDate().isEmpty()) {
LocalDate date = LocalDate.parse(profile.getToDate());
dateTo.setDate(date.getYear(), date.getMonthValue() - 1, date.getDayOfMonth());
}
}
}
private void removeCurrentProfile(){
profiles.remove(profilesCombo.getSelectionIndex());
initUIProfiles(true);
}
private void saveProfile() {
String dateFromStr = LocalDate.of(dateFrom.getYear(), dateFrom.getMonth() + 1, dateFrom.getDay()).toString();
String dateToStr = LocalDate.of(dateTo.getYear(), dateTo.getMonth() + 1, dateTo.getDay()).toString();
Profile profile = new Profile(comboApi.getText(), txtOwner.getText(), txtRepo.getText(),
txtPrefix.getText(), txtBranch.getText(), "", txtFilePath.getText(),
dateFromStr, dateToStr);
if (profiles == null){
profiles = new ArrayList<>();
}
profiles.add(profile);
initUIProfiles(true);
try {
Sink sink = Okio.sink(profileFile);
BufferedSink bufferedSink = Okio.buffer(sink);
Gson gson = new Gson();
bufferedSink.writeUtf8(gson.toJson(profiles));
bufferedSink.close();
sink.close();
} catch (IOException e) {
logger.error("IOException: " + e.getMessage(), e);
}
}
private void robIt() {
String dateFromStr = LocalDate.of(dateFrom.getYear(), dateFrom.getMonth() + 1, dateFrom.getDay()).toString();
String dateToStr = LocalDate.of(dateTo.getYear(), dateTo.getMonth() + 1, dateTo.getDay()).toString();
Configuration conf = new Configuration.ConfigurationBuilder(logger, comboApi.getText(), txtRepo.getText(), txtOwner.getText())
.branch(txtBranch.getText()).prefix(txtPrefix.getText()).filePath(txtFilePath.getText()).fromDate(dateFromStr).toDate(dateToStr)
.token(config.get(Common.CONFIG_TOKEN)).key(config.get(Common.CONFIG_KEY)).secret(config.get(Common.CONFIG_SECRET))
.username(config.get(Common.CONFIG_USERNAME)).password(config.get(Common.CONFIG_PASSWORD))
.configPath(txtConfigPath.getText()).build();
pool.execute( new RobWorker(conf) );
}
private void loadGeneratedFile() {
try {
Source source = Okio.source(new File(txtFilePath.getText()));
BufferedSource bufferedSource = Okio.buffer(source);
String content = bufferedSource.readUtf8();
txtConsole.setText(content);
bufferedSource.close();
source.close();
} catch (IOException e) {
logger.error("IOException: " + e.getMessage(), e);
}
}
public void center(Shell shell) {
Rectangle bds = shell.getDisplay().getBounds();
Point p = shell.getSize();
int nLeft = (bds.width - p.x) / 2;
int nTop = (bds.height - p.y) / 2;
shell.setBounds(nLeft, nTop, p.x, p.y);
}
public static void main(String[] args) {
Display display = new Display();
new MainSWT(display);
display.dispose();
}
}