/*******************************************************************************
* MontiCore Language Workbench
* Copyright (c) 2015, 2016, MontiCore, All rights reserved.
*
* This project is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3.0 of the License, or (at your option) any later version.
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this project. If not, see <http://www.gnu.org/licenses/>.
*******************************************************************************/
package de.monticore.genericgraphics.controller.persistence;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.gef.EditPart;
import de.monticore.genericgraphics.controller.editparts.IMCViewElementEditPart;
import de.monticore.genericgraphics.controller.persistence.util.IPersistenceUtil;
import de.monticore.genericgraphics.model.graphics.IViewElement;
import de.monticore.genericgraphics.view.layout.ILayoutAlgorithm;
import de.se_rwth.commons.logging.Log;
/**
* This class provides a default implementation of the {@link IGraphicsLoader}
* interface. This class makes use of the following classes/tools:
* <ul>
* <li>{@link IPersistenceUtil}: to import and export {@link IViewElement
* IViewElements}</li>
* <li>{@link DSLTool}: to parse an domain model file</li>
* </ul>
* <b>Note</b>: Per default the
* {@link DefaultGraphicsLoader#getDefaultParseArguments(IFile)} are passed to
* the {@link DSLTool}. If you want to use your own arguments, just ignore the
* passed ones and set your own.
*
* @author Tim Enger
*/
public class DefaultGraphicsLoader implements IGraphicsLoader {
private static final String EXTENSION = "mcvd";
/* utils */
private IPersistenceUtil util;
/* data */
private IFile mFile;
private IFile vFile;
private List<IViewElement> loadedVes;
/**
* Constructor
*
* @param util The {@link IPersistenceUtil} to use for view data files
* @param dslTool The {@link DSLTool} to use for parsing domain model files
* @param mFile The {@link IFile} of the <b>model</b> data, must not be
* <code>null</code>
* @param vFile The {@link IFile} of the <b>view</b> data, must not be
* <code>null</code>
*/
public DefaultGraphicsLoader(IPersistenceUtil util, IFile mFile, IFile vFile) {
this.util = util;
this.mFile = mFile;
this.vFile = vFile;
}
/**
* <p>
* Constructor
* </p>
* <p>
* This constructor tries to find the {@link IFile} for the view data. It
* takes the location and the name of the model {@link IFile}
* <code>mFile</code> and tries to load a view file in the same location with
* the same name, but different file extension.<br>
* If a view vile cannot be found, a new file is created.
* </p>
*
* @param util The {@link IPersistenceUtil} to use for view data files, must
* not be <code>null</code>
* @param dslTool The {@link DSLTool} to use for parsing domain model files
* @param mFile The {@link IFile} of the <b>model</b> data, must not be
* <code>null</code>
*/
public DefaultGraphicsLoader(IPersistenceUtil util, IFile mFile) {
this.util = util;
this.mFile = mFile;
initVFile();
}
private void initVFile() {
IPath loca = (IPath) mFile.getLocation().clone();
loca = loca.removeFileExtension().addFileExtension(EXTENSION);
vFile = ResourcesPlugin.getWorkspace().getRoot().getFileForLocation(loca);
}
@Override
public void saveViewData(List<EditPart> editparts, IProgressMonitor monitor) {
List<IViewElement> ves = new ArrayList<IViewElement>();
for (EditPart ep : editparts) {
if (ep instanceof IMCViewElementEditPart) {
ves.add(((IMCViewElementEditPart) ep).getViewElement());
}
}
util.exportViewElements(ves, vFile, monitor);
}
@Override
public List<IViewElement> loadViewData() {
if (getViewFile() == null) {
Log.error("0xA1107 AbstractPersistanceHandler: View File is null, cannot load view data");
return Collections.emptyList();
}
if (vFile.exists()) {
loadedVes = util.importViewElements(vFile);
}
else {
Log.error("0xA1108 view data file does not exist and thus cannot be loaded!");
}
return loadedVes;
}
@Override
public boolean combineModelViewData(List<EditPart> editparts, ILayoutAlgorithm layout) {
boolean doLayout = true;
// not using the layout algorithm at the moment
// build a map: identifier -> EditPart
Map<String, IMCViewElementEditPart> epMap = new HashMap<String, IMCViewElementEditPart>();
for (EditPart ep : editparts) {
if (ep instanceof IMCViewElementEditPart) {
IMCViewElementEditPart vep = (IMCViewElementEditPart) ep;
epMap.put(vep.getIdentifier(), vep);
}
}
// assign view elements to editparts
// and store assigned editparts
List<IMCViewElementEditPart> assignedEP = new ArrayList<IMCViewElementEditPart>();
if (getLoadedViewData() != null) {
for (IViewElement ve : getLoadedViewData()) {
IMCViewElementEditPart ep = epMap.get(ve.getIdentifier());
if (ep instanceof IMCViewElementEditPart) {
ep.setViewElement(ve);
doLayout = false;
ep.refresh();
assignedEP.add(ep);
}
}
}
// for the not assigned editparts we need to create a IViewElement
// with some default values
List<EditPart> notAssignedEP = new ArrayList<EditPart>(editparts);
notAssignedEP.removeAll(assignedEP);
// save view elements for possible layout
List<IMCViewElementEditPart> eps = new ArrayList<IMCViewElementEditPart>();
for (EditPart ep : notAssignedEP) {
if (ep instanceof IMCViewElementEditPart) {
eps.add((IMCViewElementEditPart) ep);
}
}
if (layout != null && doLayout && !eps.isEmpty()) {
layout.layout(eps);
return true;
}
return false;
}
@Override
public List<IViewElement> getLoadedViewData() {
return loadedVes;
}
@Override
public void setModelFile(IFile mFile) {
this.mFile = mFile;
}
@Override
public IFile getModelFile() {
return mFile;
}
@Override
public void setViewFile(IFile vFile) {
this.vFile = vFile;
}
@Override
public void setViewFileAccordingToModelFile() {
initVFile();
}
@Override
public IFile getViewFile() {
return vFile;
}
/**
* @param file The {@link IFile} whose absolute folder should be returned.
* @return The absolute path of the editor file.
*/
protected static String getAbsoluteFilePath(IFile file) {
return file.getRawLocation().toOSString();
}
/**
* @param file The {@link IFile} whose project folder should be returned.
* @return The project folder.
*/
protected static String getProjectFolder(IFile file) {
return file.getProject().getLocation().toString();
}
@Override
public IPersistenceUtil getPersistenceUtil() {
return util;
}
@Override
public void setPersistenceUtil(IPersistenceUtil util) {
this.util = util;
}
}