package org.openlca.app.cloud.ui.commits; import org.openlca.app.M; import java.util.ArrayList; import java.util.List; import javax.ws.rs.core.Response.Status; import org.eclipse.jface.viewers.IBaseLabelProvider; import org.eclipse.swt.SWT; import org.eclipse.swt.custom.SashForm; import org.eclipse.swt.graphics.Image; import org.eclipse.swt.widgets.Composite; import org.eclipse.ui.part.ViewPart; import org.openlca.app.App; import org.openlca.app.cloud.CloudUtil; import org.openlca.app.cloud.JsonLoader; import org.openlca.app.cloud.ui.compare.ModelLabelProvider; import org.openlca.app.cloud.ui.compare.ModelNodeBuilder; import org.openlca.app.cloud.ui.compare.ModelUtil; import org.openlca.app.cloud.ui.compare.json.DiffEditor; import org.openlca.app.cloud.ui.compare.json.JsonNode; import org.openlca.app.cloud.ui.compare.json.viewer.JsonTreeViewer.Direction; import org.openlca.app.db.Database; import org.openlca.app.rcp.images.Images; import org.openlca.app.rcp.images.Overlay; import org.openlca.app.util.Error; import org.openlca.app.util.UI; import org.openlca.app.util.tables.Tables; import org.openlca.app.viewers.BaseLabelProvider; import org.openlca.app.viewers.table.AbstractTableViewer; import org.openlca.cloud.api.RepositoryClient; import org.openlca.cloud.model.data.Commit; import org.openlca.cloud.model.data.FetchRequestData; import org.openlca.cloud.util.WebRequests.WebRequestException; import org.openlca.core.model.ModelType; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.google.gson.JsonElement; public class HistoryView extends ViewPart { public final static String ID = "views.cloud.history"; private final static Logger log = LoggerFactory.getLogger(HistoryView.class); private static HistoryView instance; private HistoryViewer historyViewer; private ReferencesViewer referencesViewer; private DiffEditor diffViewer; private Commit current; public HistoryView() { instance = this; } @Override public void createPartControl(Composite parent) { SashForm body = new SashForm(parent, SWT.VERTICAL | SWT.SMOOTH); UI.gridData(body, true, true); UI.gridLayout(body, 1); createHistoryViewer(body); SashForm secondRow = new SashForm(body, SWT.HORIZONTAL | SWT.SMOOTH); createJsonViewer(secondRow); createReferencesViewer(secondRow); refresh(); } private void createHistoryViewer(Composite parent) { historyViewer = new HistoryViewer(parent); UI.gridData(historyViewer.getViewer().getTable(), true, true); Tables.bindColumnWidths(historyViewer.getViewer(), 0.1, 0.7, 0.1, 0.1); historyViewer.addSelectionChangedListener((commit) -> { if (commit == null) return; if (commit.equals(current)) return; current = commit; instance.diffViewer.setInput(null); loadReferences(commit); }); } private void createJsonViewer(Composite parent) { diffViewer = DiffEditor.forViewing(parent); diffViewer.setLabels(M.SelectedCommit, M.PreviousCommit); diffViewer.initialize(null, new ModelLabelProvider(), ModelUtil.getDependencyResolver(), Direction.LEFT_TO_RIGHT); } private void createReferencesViewer(Composite parent) { referencesViewer = new ReferencesViewer(parent); UI.gridData(referencesViewer.getViewer().getTable(), true, true); referencesViewer.addSelectionChangedListener((ref) -> { if (ref == null) return; if (!Database.isConnected()) return; if (ref.equals(referencesViewer.lastSelection)) return; referencesViewer.lastSelection = ref; RepositoryClient client = Database.getRepositoryClient(); JsonLoader loader = CloudUtil.getJsonLoader(client); loader.setCommitId(current.id); List<JsonNode> nodes = new ArrayList<>(); App.runWithProgress("Loading data", () -> { JsonElement currentElement = loader.getRemoteJson(ref); JsonElement previousElement = null; String previousCommit = loadPreviousCommit(ref); if (previousCommit != null) { loader.setCommitId(previousCommit); previousElement = loader.getRemoteJson(ref); } nodes.add(new ModelNodeBuilder().build(currentElement, previousElement)); }); diffViewer.setInput(nodes.get(0)); }); } private String loadPreviousCommit(FetchRequestData ref) { RepositoryClient client = Database.getRepositoryClient(); try { return client.getPreviousReference(ref.type, ref.refId, current.id); } catch (WebRequestException e) { if (e.getErrorCode() == Status.NOT_FOUND.getStatusCode()) return null; log.warn("Error loading previous commit", e); Error.showBox(e.getMessage()); return null; } } private void loadCommitHistory() { RepositoryClient client = Database.getRepositoryClient(); try { historyViewer.setInput(client.fetchCommitHistory()); } catch (Exception e) { log.warn("Error loading commit history", e); Error.showBox(e.getMessage()); } } public static void refresh() { if (instance == null) return; instance.historyViewer.setInput(new Commit[0]); instance.referencesViewer.setInput(new FetchRequestData[0]); instance.diffViewer.setInput(null); if (Database.isConnected()) { instance.loadCommitHistory(); return; } } @Override public void dispose() { instance = null; super.dispose(); } private void loadReferences(Commit commit) { if (!Database.isConnected()) return; RepositoryClient client = Database.getRepositoryClient(); List<FetchRequestData> references = new ArrayList<>(); App.runWithProgress("Loading references", () -> { try { references.addAll(client.getReferences(commit.id)); } catch (Exception e) { log.warn("Error loading commit history", e); Error.showBox(e.getMessage()); } }); for (FetchRequestData data : new ArrayList<>(references)) if (!data.type.isCategorized()) references.remove(data); referencesViewer.setInput(references); } @Override public void setFocus() { } private class ReferencesViewer extends AbstractTableViewer<FetchRequestData> { private FetchRequestData lastSelection; private ReferencesViewer(Composite parent) { super(parent); } @Override protected IBaseLabelProvider getLabelProvider() { return new ReferencesLabel(); } } private class ReferencesLabel extends BaseLabelProvider { @Override public String getText(Object element) { if (!(element instanceof FetchRequestData)) return null; FetchRequestData data = (FetchRequestData) element; return data.fullPath; } @Override public Image getImage(Object element) { if (!(element instanceof FetchRequestData)) return null; FetchRequestData data = (FetchRequestData) element; Overlay overlay = null; if (data.isAdded()) overlay = Overlay.ADDED; else if (data.isDeleted()) overlay = Overlay.DELETED; if (data.type == ModelType.CATEGORY) return Images.getForCategory(data.categoryType, overlay); return Images.get(data.type, overlay); } } }