blob: 492d8b96ab648c04335e230dc06b3b94a555f830 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
*/
package org.apache.openaz.xacml.admin.view.windows;
import java.io.File;
import java.io.IOException;
import java.nio.file.Path;
import java.nio.file.Paths;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.eclipse.jgit.api.Git;
import org.eclipse.jgit.api.Status;
import org.eclipse.jgit.api.errors.GitAPIException;
import org.eclipse.jgit.dircache.DirCache;
import org.eclipse.jgit.dircache.DirCacheEntry;
import org.eclipse.jgit.errors.NoWorkTreeException;
import org.apache.openaz.xacml.admin.XacmlAdminUI;
import org.apache.openaz.xacml.admin.model.GitStatusContainer;
import org.apache.openaz.xacml.admin.model.GitStatusContainer.GitEntry;
import org.apache.openaz.xacml.admin.model.GitStatusContainer.StatusItem;
import org.apache.openaz.xacml.admin.util.AdminNotification;
import com.vaadin.annotations.AutoGenerated;
import com.vaadin.data.Buffered.SourceException;
import com.vaadin.data.Item;
import com.vaadin.data.Validator.InvalidValueException;
import com.vaadin.event.FieldEvents.TextChangeEvent;
import com.vaadin.event.FieldEvents.TextChangeListener;
import com.vaadin.event.ShortcutAction.KeyCode;
import com.vaadin.ui.Alignment;
import com.vaadin.ui.Button;
import com.vaadin.ui.Button.ClickEvent;
import com.vaadin.ui.Button.ClickListener;
import com.vaadin.ui.Table;
import com.vaadin.ui.Table.ColumnGenerator;
import com.vaadin.ui.TextArea;
import com.vaadin.ui.VerticalLayout;
import com.vaadin.ui.Window;
public class GitPushWindow extends Window {
/*- VaadinEditorProperties={"grid":"RegularGrid,20","showGrid":true,"snapToGrid":true,"snapToObject":true,"movingGuides":false,"snappingDistance":10} */
@AutoGenerated
private VerticalLayout mainLayout;
@AutoGenerated
private Button buttonPush;
@AutoGenerated
private Table tableChanges;
@AutoGenerated
private TextArea textAreaComments;
/**
*
*/
private static final long serialVersionUID = 1L;
private static final Log logger = LogFactory.getLog(GitPushWindow.class);
private final GitPushWindow self = this;
private final GitStatusContainer container;
private final Git git;
private final File target;
private boolean isSaved = false;
/**
* The constructor should first build the main layout, set the
* composition root and then do any custom initialization.
*
* The constructor will not be automatically regenerated by the
* visual editor.
* @param git
* @param status
*/
public GitPushWindow(Git git, File target, Status status) {
buildMainLayout();
//setCompositionRoot(mainLayout);
setContent(mainLayout);
//
// Save data
//
this.git = git;
this.target = target;
this.container = new GitStatusContainer(status);
//
// Set our shortcuts
//
this.setCloseShortcut(KeyCode.ESCAPE);
//
// Initialize GUI
//
this.initializeText();
this.initializeTable(status);
this.initializeButtons();
//
// Focus
//
this.textAreaComments.focus();
}
protected void initializeText() {
this.textAreaComments.setImmediate(true);
this.textAreaComments.addTextChangeListener(new TextChangeListener() {
private static final long serialVersionUID = 1L;
@Override
public void textChange(TextChangeEvent event) {
if (event.getText().isEmpty()) {
self.buttonPush.setEnabled(false);
} else {
if (self.container.getConflictCount() == 0) {
self.buttonPush.setEnabled(true);
} else {
self.buttonPush.setEnabled(false);
}
}
}
});
}
protected void initializeTable(Status status) {
//
// Setup the table
//
this.tableChanges.setContainerDataSource(this.container);
this.tableChanges.setPageLength(this.container.size());
this.tableChanges.setImmediate(true);
//
// Generate column
//
this.tableChanges.addGeneratedColumn("Entry", new ColumnGenerator() {
private static final long serialVersionUID = 1L;
@Override
public Object generateCell(Table source, Object itemId, Object columnId) {
Item item = self.container.getItem(itemId);
assert item != null;
if (item instanceof StatusItem) {
return self.generateGitEntryComponent(((StatusItem) item).getGitEntry());
}
assert item instanceof StatusItem;
return null;
}
});
}
protected Object generateGitEntryComponent(final GitEntry entry) {
//
// If its conflicting, take care of it
//
if (entry.isConflicting()) {
return this.generateConflictingEntry(entry);
}
if (entry.isUntracked()) {
return this.generateUntrackedEntry(entry);
}
/*
if (entry.isChanged() ||
entry.isModified() ||
entry.isUncommitted()) {
return this.generateUncommittedEntry(entry);
}
*/
return null;
}
protected Object generateConflictingEntry(final GitEntry entry) {
Button resolve = new Button("Resolve");
resolve.setImmediate(true);
resolve.addClickListener(new ClickListener() {
private static final long serialVersionUID = 1L;
@Override
public void buttonClick(ClickEvent event) {
}
});
return resolve;
}
protected Object generateUntrackedEntry(final GitEntry entry) {
Button add = new Button("Add");
add.setImmediate(true);
add.addClickListener(new ClickListener() {
private static final long serialVersionUID = 1L;
@Override
public void buttonClick(ClickEvent event) {
try {
DirCache cache = self.git.add().addFilepattern(entry.getName()).call();
DirCacheEntry cacheEntry = cache.getEntry(entry.getName());
assert cacheEntry != null;
if (cacheEntry == null) {
return;
}
if (cacheEntry.isMerged()) {
self.refreshStatus();
}
} catch (GitAPIException e) {
String error = "Failed to add: " + e.getLocalizedMessage();
logger.error(error);
AdminNotification.error(error);
}
}
});
return add;
}
protected Object generateUncommittedEntry(final GitEntry entry) {
Button commit = new Button("Commit");
commit.setImmediate(true);
commit.addClickListener(new ClickListener() {
private static final long serialVersionUID = 1L;
@Override
public void buttonClick(ClickEvent event) {
}
});
return commit;
}
protected void initializeButtons() {
this.buttonPush.setEnabled(false);
this.buttonPush.addClickListener(new ClickListener() {
private static final long serialVersionUID = 1L;
@Override
public void buttonClick(ClickEvent event) {
try {
//
// Commit
//
self.textAreaComments.commit();
//
// Mark as saved
//
self.isSaved = true;
//
// Close the window
//
self.close();
} catch(SourceException | InvalidValueException idontcare) { //NOPMD
//
// Vaadin will highlight the failed requirement or validation
//
}
}
});
}
protected void refreshStatus() {
try {
//
// Grab our working repository
//
Path repoPath = ((XacmlAdminUI)getUI()).getUserGitPath();
final Git git = Git.open(repoPath.toFile());
//
// Get our status
//
final String base;
Status status;
if (target == null) {
base = ".";
} else {
Path relativePath = repoPath.relativize(Paths.get(target.getPath()));
base = relativePath.toString();
}
if (logger.isDebugEnabled()) {
logger.debug("Status on base: " + base);
}
status = git.status().addPath(base).call();
//
// Pass it to our container
//
this.container.refreshStatus(status);
this.tableChanges.refreshRowCache();
} catch (NoWorkTreeException | IOException | GitAPIException e) {
String error = "Failed to refresh status: " + e.getLocalizedMessage();
logger.error(error);
}
}
public boolean isSaved() {
return this.isSaved;
}
public String getComment() {
return this.textAreaComments.getValue();
}
@AutoGenerated
private VerticalLayout buildMainLayout() {
// common part: create layout
mainLayout = new VerticalLayout();
mainLayout.setImmediate(false);
mainLayout.setWidth("-1px");
mainLayout.setHeight("-1px");
mainLayout.setMargin(true);
mainLayout.setSpacing(true);
// top-level component properties
setWidth("-1px");
setHeight("-1px");
// textAreaComments
textAreaComments = new TextArea();
textAreaComments.setCaption("Add Comments");
textAreaComments.setImmediate(false);
textAreaComments
.setDescription("Enter comments that reflect the changes you have made to the repository domains and/or policy files.");
textAreaComments.setWidth("400px");
textAreaComments.setHeight("-1px");
textAreaComments.setInvalidAllowed(false);
textAreaComments.setRequired(true);
textAreaComments
.setInputPrompt("Eg. Add new rule for employees in marketing department.");
mainLayout.addComponent(textAreaComments);
// tableChanges
tableChanges = new Table();
tableChanges.setCaption("Changes To Be Pushed");
tableChanges.setImmediate(false);
tableChanges.setWidth("100.0%");
tableChanges.setHeight("-1px");
mainLayout.addComponent(tableChanges);
mainLayout.setExpandRatio(tableChanges, 1.0f);
// buttonPush
buttonPush = new Button();
buttonPush.setCaption("Push Changes");
buttonPush.setImmediate(true);
buttonPush.setWidth("-1px");
buttonPush.setHeight("-1px");
mainLayout.addComponent(buttonPush);
mainLayout.setComponentAlignment(buttonPush, new Alignment(48));
return mainLayout;
}
}