package org.openlca.app.editors; import java.util.ArrayList; import java.util.List; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.jface.dialogs.InputDialog; import org.eclipse.jface.window.Window; import org.eclipse.ui.IEditorInput; import org.eclipse.ui.IEditorSite; import org.eclipse.ui.PartInitException; import org.eclipse.ui.forms.editor.FormEditor; import org.openlca.app.App; import org.openlca.app.Event; import org.openlca.app.EventHandler; import org.openlca.app.M; import org.openlca.app.db.Cache; import org.openlca.app.db.Database; import org.openlca.app.navigation.Navigator; import org.openlca.app.rcp.images.Images; import org.openlca.app.util.Labels; import org.openlca.app.util.UI; import org.openlca.core.database.BaseDao; import org.openlca.core.database.EntityCache; import org.openlca.core.model.CategorizedEntity; import org.openlca.core.model.Version; import org.openlca.core.model.descriptors.BaseDescriptor; import org.openlca.util.Strings; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.google.common.eventbus.EventBus; public abstract class ModelEditor<T extends CategorizedEntity> extends FormEditor implements IEditor { private Logger log = LoggerFactory.getLogger(getClass()); private boolean dirty; private T model; private BaseDao<T> dao; private Class<T> modelClass; private EventBus eventBus = new EventBus(); private List<EventHandler> savedHandlers = new ArrayList<>(); public ModelEditor(Class<T> modelClass) { this.modelClass = modelClass; } /** * Calls the given event handler AFTER the model in this editor was saved. */ public void onSaved(EventHandler handler) { savedHandlers.add(handler); } public EventBus getEventBus() { return eventBus; } public void postEvent(String message, Object source) { eventBus.post(new Event(message, source)); } @Override public void init(IEditorSite site, IEditorInput input) throws PartInitException { super.init(site, input); log.trace("open " + modelClass.getSimpleName() + " editor {}", input); ModelEditorInput i = (ModelEditorInput) input; setPartName(input.getName()); setTitleImage(Images.get(i.getDescriptor())); try { dao = new BaseDao<>(modelClass, Database.get()); model = dao.getForId(i.getDescriptor().getId()); eventBus.register(this); } catch (Exception e) { log.error("failed to load " + modelClass.getSimpleName() + " from editor input", e); } } @Override public void doSave(IProgressMonitor monitor) { try { if (monitor != null) monitor.beginTask(M.Save + " " + modelClass.getSimpleName() + "...", IProgressMonitor.UNKNOWN); model.setLastChange(System.currentTimeMillis()); Version version = new Version(model.getVersion()); version.incUpdate(); model.setVersion(version.getValue()); model = dao.update(model); doAfterUpdate(); if (monitor != null) monitor.done(); } catch (Exception e) { log.error("failed to update " + modelClass.getSimpleName()); } } public void updateModel() { if (model == null) return; if (model.getId() == 0) return; model = dao.getForId(model.getId()); } protected void doAfterUpdate() { setDirty(false); BaseDescriptor descriptor = getEditorInput().getDescriptor(); EntityCache cache = Cache.getEntityCache(); cache.refresh(descriptor.getClass(), descriptor.getId()); cache.invalidate(modelClass, model.getId()); this.setPartName(Labels.getDisplayName(model)); Cache.evict(descriptor); for (EventHandler handler : savedHandlers) handler.handleEvent(); Navigator.refresh(Navigator.findElement(descriptor)); } @Override public ModelEditorInput getEditorInput() { return (ModelEditorInput) super.getEditorInput(); } @Override public void setDirty(boolean b) { if (dirty != b) { dirty = b; editorDirtyStateChanged(); } } @Override public boolean isDirty() { return dirty; } @Override @SuppressWarnings("unchecked") public void doSaveAs() { InputDialog diag = new InputDialog(UI.shell(), M.SaveAs, M.SaveAs, model.getName() + " - Copy", (name) -> { if (Strings.nullOrEmpty(name)) return M.NameCannotBeEmpty; if (Strings.nullOrEqual(name, model.getName())) return M.NameShouldBeDifferent; return null; }); if (diag.open() != Window.OK) return; String newName = diag.getValue(); try { T clone = (T) model.clone(); clone.setName(newName); clone = dao.insert(clone); App.openEditor(clone); } catch (Exception e) { log.error("failed to save " + model + " as " + newName, e); } } @Override public boolean isSaveAsAllowed() { return true; } public T getModel() { return model; } }