/*
* (c) Copyright 2010-2011 AgileBirds
*
* This file is part of OpenFlexo.
*
* OpenFlexo is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* OpenFlexo 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 Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with OpenFlexo. If not, see <http://www.gnu.org/licenses/>.
*
*/
package org.openflexo.sgmodule.controller;
import java.util.Collection;
import java.util.Hashtable;
import java.util.Map;
import java.util.Vector;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.openflexo.components.AskParametersDialog;
import org.openflexo.components.ProgressWindow;
import org.openflexo.foundation.FlexoEditor;
import org.openflexo.foundation.FlexoModelObject;
import org.openflexo.foundation.cg.CGFile;
import org.openflexo.foundation.cg.CGObject;
import org.openflexo.foundation.cg.GenerationRepository;
import org.openflexo.foundation.cg.action.AbstractGCAction;
import org.openflexo.foundation.cg.templates.CGTemplate;
import org.openflexo.foundation.cg.templates.CGTemplateFile;
import org.openflexo.foundation.param.CheckboxParameter;
import org.openflexo.foundation.param.RadioButtonListParameter;
import org.openflexo.foundation.rm.FlexoGeneratedResource;
import org.openflexo.foundation.rm.FlexoProject;
import org.openflexo.foundation.rm.ResourceUpdateHandler;
import org.openflexo.foundation.rm.cg.CGRepositoryFileResource;
import org.openflexo.foundation.rm.cg.ContentSource;
import org.openflexo.foundation.sg.GeneratedSources;
import org.openflexo.foundation.sg.SourceRepository;
import org.openflexo.foundation.sg.implmodel.ImplementationModel;
import org.openflexo.foundation.sg.implmodel.TechnologyModelObject;
import org.openflexo.foundation.sg.implmodel.TechnologyModuleImplementation;
import org.openflexo.generator.AbstractProjectGenerator;
import org.openflexo.generator.action.AcceptDiskUpdate;
import org.openflexo.generator.action.GCAction.ProjectGeneratorFactory;
import org.openflexo.generator.exception.GenerationException;
import org.openflexo.inspector.InspectableObject;
import org.openflexo.localization.FlexoLocalization;
import org.openflexo.module.FlexoModule;
import org.openflexo.module.GeneratedResourceModifiedChoice;
import org.openflexo.selection.SelectionManager;
import org.openflexo.sg.action.AcceptDiskUpdateAndReinjectInModel;
import org.openflexo.sg.action.ReinjectInModel;
import org.openflexo.sg.generator.ProjectGenerator;
import org.openflexo.sgmodule.SGPreferences;
import org.openflexo.sgmodule.controller.action.SGControllerActionInitializer;
import org.openflexo.sgmodule.controller.browser.SGBrowser;
import org.openflexo.sgmodule.view.CGFileModuleView;
import org.openflexo.sgmodule.view.SGBrowserView;
import org.openflexo.sgmodule.view.SGFooter;
import org.openflexo.sgmodule.view.SGMainPane;
import org.openflexo.sgmodule.view.menu.SGMenuBar;
import org.openflexo.sgmodule.view.popup.CGFileVersionPopup;
import org.openflexo.view.FlexoMainPane;
import org.openflexo.view.ModuleView;
import org.openflexo.view.controller.ControllerActionInitializer;
import org.openflexo.view.controller.FlexoController;
import org.openflexo.view.menu.FlexoMenuBar;
/**
* Controller for this module
*
* @author sylvain
*/
public class SGController extends FlexoController implements ProjectGeneratorFactory {
private static final Logger logger = Logger.getLogger(SGController.class.getPackage().getName());
protected Map<SourceRepository, ProjectGenerator> _projectGenerators;
protected SGFooter _footer;
public CodeGenerationPerspective CODE_GENERATION_PERSPECTIVE;
public VersionningPerspective VERSIONNING_PERSPECTIVE;
public ModelReinjectionPerspective MODEL_REINJECTION_PERSPECTIVE;
private SGBrowser _browser;
private SGBrowserView _browserView;
private SourceRepository _lastEditedCGRepository;
protected Vector<SourceRepository> observedRepositories = new Vector<SourceRepository>();
/**
* Default constructor
*/
public SGController(FlexoModule module) {
super(module);
}
@Override
protected void initializePerspectives() {
createFooter();
_browser = new SGBrowser(this);
_browserView = new SGBrowserView(this, _browser) {
@Override
public void treeDoubleClick(FlexoModelObject object) {
super.treeDoubleClick(object);
if (object instanceof SourceRepository) {
selectAndFocusObject(object);
}
}
};
addToPerspectives(CODE_GENERATION_PERSPECTIVE = new CodeGenerationPerspective(this));
addToPerspectives(VERSIONNING_PERSPECTIVE = new VersionningPerspective(this));
addToPerspectives(MODEL_REINJECTION_PERSPECTIVE = new ModelReinjectionPerspective(this));
}
public SGBrowserView getBrowserView() {
return _browserView;
}
@Override
protected SelectionManager createSelectionManager() {
return new SGSelectionManager(this);
}
@Override
public ControllerActionInitializer createControllerActionInitializer() {
return new SGControllerActionInitializer(this);
}
/**
* Creates a new instance of MenuBar for the module this controller refers to
*
* @return
*/
@Override
protected FlexoMenuBar createNewMenuBar() {
return new SGMenuBar(this);
}
@Override
protected FlexoMainPane createMainPane() {
return new SGMainPane(this);
}
/**
* Init inspectors
*/
@Override
public void initInspectors() {
super.initInspectors();
if (useNewInspectorScheme()) {
loadInspectorGroup("Generator");
}
if (useOldInspectorScheme()) {
getSelectionManager().addObserver(getSharedInspectorController());
}
}
public void initProgressWindow(String msg, int steps) {
ProgressWindow.showProgressWindow(msg, steps);
}
public void refreshProgressWindow(String msg) {
ProgressWindow.setProgressInstance(msg);
}
public void refreshSecondaryProgressWindow(String msg) {
ProgressWindow.setSecondaryProgressInstance(msg);
}
public void disposeProgressWindow() {
ProgressWindow.hideProgressWindow();
}
public SGBrowser getBrowser() {
return _browser;
}
/**
* Select the view representing supplied object, if this view exists. Try all to really display supplied object, even if required view
* is not the current displayed view
*
* @param object
* : the object to focus on
*/
@Override
public void selectAndFocusObject(FlexoModelObject object) {
if (object instanceof CGFile) {
setCurrentEditedObjectAsModuleView(object);
}
getSelectionManager().setSelectedObject(object);
}
// ================================================
// ============ Exception management ==============
// ================================================
@Override
public boolean handleException(InspectableObject inspectable, String propertyName, Object value, Throwable exception) {
// TODO: Handles here exceptions that may be thrown through the inspector
return super.handleException(inspectable, propertyName, value, exception);
}
@Override
public AbstractProjectGenerator<? extends GenerationRepository> generatorForRepository(GenerationRepository repository) {
if (repository instanceof SourceRepository) {
return getProjectGenerator((SourceRepository) repository);
} else {
if (logger.isLoggable(Level.SEVERE)) {
logger.severe("Cannot create project generator for " + repository);
}
}
return null;
}
public ProjectGenerator getProjectGenerator(SourceRepository repository) {
ProjectGenerator returned = _projectGenerators.get(repository);
if (!repository.isConnected()) {
return returned;
}
if (returned == null) {
try {
returned = new ProjectGenerator(getProject(), repository);
} catch (GenerationException e) {
showError(e.getLocalizedMessage());
return null;
}
_projectGenerators.put(repository, returned);
}
return returned;
}
public Collection<ProjectGenerator> getProjectGenerators() {
return _projectGenerators.values();
}
@Override
public void updateEditor(FlexoEditor from, FlexoEditor to) {
super.updateEditor(from, to);
if (from != null && from.getProject() != null) {
from.getProject().getGeneratedCode().setFactory(null);
}
if (to != null && to.getResourceUpdateHandler() != null) {
to.getResourceUpdateHandler().setGeneratedResourceModifiedHook(_CGGeneratedResourceModifiedHook);
}
if (to != null && to.getProject() != null) {
to.getProject().getGeneratedCode().setFactory(this);
}
_browser.setRootObject(to != null && to.getProject() != null ? to.getProject().getGeneratedSources() : null);
}
@Override
public FlexoModelObject getDefaultObjectToSelect(FlexoProject project) {
// Implement this
return null;
}
public SourceRepository getCurrentGeneratedCodeRepository() {
FlexoModelObject object = getCurrentDisplayedObjectAsModuleView();
if (object instanceof CGObject && AbstractGCAction.repositoryForObject((CGObject) object) instanceof SourceRepository) {
return (SourceRepository) AbstractGCAction.repositoryForObject((CGObject) object);
}
return null;
}
public Vector<SourceRepository> getObservedRepositories() {
return observedRepositories;
}
public void refreshFooter() {
_footer.refresh();
}
private void createFooter() {
_footer = new SGFooter(this);
}
public GenerationRepository getLastEditedCGRepository() {
return _lastEditedCGRepository;
}
private Hashtable<CGFile, Hashtable<ContentSource, CGFileVersionPopup>> storedPopups = new Hashtable<CGFile, Hashtable<ContentSource, CGFileVersionPopup>>();
public CGFileVersionPopup getPopupShowingFileVersion(CGFile aFile, ContentSource contentSource) {
if (storedPopups.get(aFile) == null) {
Hashtable<ContentSource, CGFileVersionPopup> newHashtable = new Hashtable<ContentSource, CGFileVersionPopup>();
storedPopups.put(aFile, newHashtable);
}
if (storedPopups.get(aFile).get(contentSource) == null) {
CGFileVersionPopup newPopup = new CGFileVersionPopup(aFile, contentSource, this);
storedPopups.get(aFile).put(contentSource, newPopup);
}
return storedPopups.get(aFile).get(contentSource);
}
public void deletePopupShowingFileVersion(CGFile aFile, ContentSource contentSource) {
storedPopups.get(aFile).remove(contentSource);
}
public SGFooter getFooter() {
return _footer;
}
private CGGeneratedResourceModifiedHook _CGGeneratedResourceModifiedHook;
public class CGGeneratedResourceModifiedHook implements ResourceUpdateHandler.GeneratedResourceModifiedHook {
protected CGGeneratedResourceModifiedHook() {
}
@Override
public void handleGeneratedResourceModified(FlexoGeneratedResource aGeneratedResource) {
if (aGeneratedResource instanceof CGRepositoryFileResource) {
CGRepositoryFileResource generatedResource = (CGRepositoryFileResource) aGeneratedResource;
GeneratedResourceModifiedChoice choice = SGPreferences.getGeneratedResourceModifiedChoice();
if (choice == GeneratedResourceModifiedChoice.ASK) {
RadioButtonListParameter<String> whatToDo = new RadioButtonListParameter<String>("whatToDo",
"what_would_you_like_to_do", GeneratedResourceModifiedChoice.IGNORE.getLocalizedName(),
GeneratedResourceModifiedChoice.IGNORE.getLocalizedName(),
GeneratedResourceModifiedChoice.REINJECT_IN_MODEL.getLocalizedName(),
GeneratedResourceModifiedChoice.AUTOMATICALLY_REINJECT_IN_MODEL.getLocalizedName(),
GeneratedResourceModifiedChoice.ACCEPT.getLocalizedName(),
GeneratedResourceModifiedChoice.ACCEPT_AND_REINJECT.getLocalizedName(),
GeneratedResourceModifiedChoice.ACCEPT_AND_AUTOMATICALLY_REINJECT.getLocalizedName());
CheckboxParameter rememberMyChoice = new CheckboxParameter("rememberMyChoice", "remember_my_choice", false);
AskParametersDialog dialog = AskParametersDialog.createAskParametersDialog(getProject(), null,
FlexoLocalization.localizedForKey("resource_edited"), FlexoLocalization.localizedForKey("resource") + " "
+ generatedResource.getFileName() + " " + FlexoLocalization.localizedForKey("has_been_edited"),
whatToDo, rememberMyChoice);
if (dialog.getStatus() == AskParametersDialog.VALIDATE) {
if (whatToDo.getValue().equals(GeneratedResourceModifiedChoice.IGNORE.getLocalizedName())) {
choice = GeneratedResourceModifiedChoice.IGNORE;
} else if (whatToDo.getValue().equals(GeneratedResourceModifiedChoice.REINJECT_IN_MODEL.getLocalizedName())) {
choice = GeneratedResourceModifiedChoice.REINJECT_IN_MODEL;
} else if (whatToDo.getValue().equals(
GeneratedResourceModifiedChoice.AUTOMATICALLY_REINJECT_IN_MODEL.getLocalizedName())) {
choice = GeneratedResourceModifiedChoice.AUTOMATICALLY_REINJECT_IN_MODEL;
} else if (whatToDo.getValue().equals(GeneratedResourceModifiedChoice.ACCEPT.getLocalizedName())) {
choice = GeneratedResourceModifiedChoice.ACCEPT;
} else if (whatToDo.getValue().equals(GeneratedResourceModifiedChoice.ACCEPT_AND_REINJECT.getLocalizedName())) {
choice = GeneratedResourceModifiedChoice.ACCEPT_AND_REINJECT;
} else if (whatToDo.getValue().equals(
GeneratedResourceModifiedChoice.ACCEPT_AND_AUTOMATICALLY_REINJECT.getLocalizedName())) {
choice = GeneratedResourceModifiedChoice.ACCEPT_AND_AUTOMATICALLY_REINJECT;
}
if (rememberMyChoice.getValue()) {
SGPreferences.setGeneratedResourceModifiedChoice(choice);
}
}
}
if (logger.isLoggable(Level.FINE)) {
logger.fine("I will perform " + choice.getLocalizedName());
}
if (choice == GeneratedResourceModifiedChoice.ASK) {
choice = GeneratedResourceModifiedChoice.IGNORE;
}
if (generatedResource.getCGFile() != null) {
// First of all, notify resource changed
generatedResource.notifyResourceChangedOnDisk();
Vector<CGObject> resourceChangedOnDisk = new Vector<CGObject>();
resourceChangedOnDisk.add(generatedResource.getCGFile());
if (choice == GeneratedResourceModifiedChoice.IGNORE) {
} else if (choice == GeneratedResourceModifiedChoice.REINJECT_IN_MODEL) {
ReinjectInModel.actionType.makeNewAction(generatedResource.getCGFile(), resourceChangedOnDisk, getEditor())
.doAction();
} else if (choice == GeneratedResourceModifiedChoice.AUTOMATICALLY_REINJECT_IN_MODEL) {
ReinjectInModel reinjectInModelAction = ReinjectInModel.actionType.makeNewAction(generatedResource.getCGFile(),
resourceChangedOnDisk, getEditor());
reinjectInModelAction.setAskReinjectionContext(false);
reinjectInModelAction.doAction();
} else if (choice == GeneratedResourceModifiedChoice.ACCEPT) {
AcceptDiskUpdate.actionType.makeNewAction(generatedResource.getCGFile(), null, getEditor()).doAction();
} else if (choice == GeneratedResourceModifiedChoice.ACCEPT_AND_REINJECT) {
AcceptDiskUpdateAndReinjectInModel.actionType.makeNewAction(generatedResource.getCGFile(), resourceChangedOnDisk,
getEditor()).doAction();
} else if (choice == GeneratedResourceModifiedChoice.ACCEPT_AND_AUTOMATICALLY_REINJECT) {
AcceptDiskUpdateAndReinjectInModel acceptDiskUpdateAndReinjectInModelAction = AcceptDiskUpdateAndReinjectInModel.actionType
.makeNewAction(generatedResource.getCGFile(), resourceChangedOnDisk, getEditor());
acceptDiskUpdateAndReinjectInModelAction.setAskReinjectionContext(false);
acceptDiskUpdateAndReinjectInModelAction.doAction();
}
}
}
}
}
public CGGeneratedResourceModifiedHook getCGGeneratedResourceModifiedHook() {
return _CGGeneratedResourceModifiedHook;
}
public void setCGGeneratedResourceModifiedHook(CGGeneratedResourceModifiedHook generatedResourceModifiedHook) {
_CGGeneratedResourceModifiedHook = generatedResourceModifiedHook;
}
@Override
public String getWindowTitleforObject(FlexoModelObject object) {
if (object instanceof ImplementationModel) {
return FlexoLocalization.localizedForKey("implementation_model") + " " + object.getName();
}
if (object instanceof TechnologyModuleImplementation) {
return ((TechnologyModuleImplementation) object).getTechnologyModuleDefinition().getName();
}
if (object instanceof TechnologyModelObject) {
return ((TechnologyModelObject) object).getName();
}
if (object instanceof GeneratedSources) {
return FlexoLocalization.localizedForKey("generated_sources");
}
if (object instanceof SourceRepository) {
return ((SourceRepository) object).getName();
}
if (object instanceof CGFile) {
CGFile cgFile = (CGFile) object;
return cgFile.getResource().getFile().getName()
+ (cgFile.isEdited() ? "[" + FlexoLocalization.localizedForKey("edited") + "]" : "");
}
if (object instanceof CGTemplate) {
CGTemplate cgTemplateFile = (CGTemplate) object;
return cgTemplateFile.getTemplateName()
+ (cgTemplateFile instanceof CGTemplateFile && ((CGTemplateFile) cgTemplateFile).isEdited() ? "["
+ FlexoLocalization.localizedForKey("edited") + "]" : "");
}
return null;
}
public void notifyModuleViewDisplayed(ModuleView<?> moduleView) {
if (moduleView.getRepresentedObject() instanceof CGObject
&& AbstractGCAction.repositoryForObject((CGObject) moduleView.getRepresentedObject()) instanceof SourceRepository) {
_lastEditedCGRepository = (SourceRepository) AbstractGCAction.repositoryForObject((CGObject) moduleView.getRepresentedObject());
}
refreshFooter();
if (moduleView instanceof CGFileModuleView) {
((CGFileModuleView) moduleView).refresh();
}
}
}