package com.openMap1.mapper.actions;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.Vector;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IProject;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EPackage;
import org.eclipse.jface.action.Action;
import org.eclipse.ui.ISharedImages;
import org.eclipse.ui.PlatformUI;
import com.openMap1.mapper.core.MapperException;
import com.openMap1.mapper.query.DataSource;
import com.openMap1.mapper.reader.XOReader;
import com.openMap1.mapper.util.EclipseFileUtil;
import com.openMap1.mapper.util.ModelUtil;
import com.openMap1.mapper.views.ClassModelView;
import com.openMap1.mapper.views.DataSourceView;
import com.openMap1.mapper.views.LabelledEClass;
import com.openMap1.mapper.views.WorkBenchUtil;
public class WriteCrossMappingsAction extends Action{
private DataSourceView dataSourceView;
private boolean tracing = true;
private void trace(String s) {if (tracing) System.out.println(s);}
private Vector<DataSource> chosenSources = new Vector<DataSource>();
private IProject theProject;
private IFolder mappingSetFolder;
private Vector<String[]> mappingRows;
//private String NO_MAPPINGS = "$No mappings in data source";
private boolean testing = false;
//-----------------------------------------------------------------------------------------
// constructor
//-----------------------------------------------------------------------------------------
public WriteCrossMappingsAction(DataSourceView dataSourceView)
{
this.dataSourceView = dataSourceView;
setText("Write Cross-mappings Table");
setToolTipText("Write a table of cross-mappings between active data sources");
setImageDescriptor(PlatformUI.getWorkbench().getSharedImages().
getImageDescriptor(ISharedImages.IMG_OBJS_INFO_TSK));
setEnabled(testing);
}
public void run()
{
trace("Writing cross-mappings");
try
{
// (1) Check that there are some active data sources
dataSourceView.refreshAllActiveSources(false);
if (dataSourceView.getActiveDataSources().size() == 0)
{throw new MapperException("There are no active data sources for which to write cross-mappings");}
// (2) choose the data sources, without duplicates
chooseSourcesForCrossMappings();
// (3) set up the IFile to be written to
theProject = chosenSources.get(0).getProject();
mappingSetFolder = theProject.getFolder("MappingSets");
String fileName = "crossMappings_" + activeCodes() + ".csv";
IFile crossMappingsFile = mappingSetFolder.getFile(fileName);
if (crossMappingsFile.exists()) crossMappingsFile.delete(true, null);
// (4) Initialise the rows to be written to the table
mappingRows = new Vector<String[]>();
makeHeaderRow();
// (5) find the root class of the mapped class model
EPackage mappedModel = chosenSources.get(0).getFreshMappedStructure().getClassModelRoot();
if (mappedModel == null) throw new MapperException("Cannot find mapped class model");
LabelledEClass rootLabelledClass = ClassModelView.getRootLabelledEClass(mappedModel);
if (rootLabelledClass == null) throw new MapperException("There is no entry class for the mapped class model");
EClass rootClass = rootLabelledClass.eClass();
// (6) recursive descent of the class model
String[] subsets = new String[chosenSources.size()];
// assume that mappings to the root class all have only the subset ""
for (int i = 0; i < chosenSources.size(); i++) subsets[i] = "";
String assocName = "";
addMappingRows(assocName,rootClass,subsets);
// (7) write out the file
EclipseFileUtil.writeCSVFile(mappingRows, crossMappingsFile);
}
catch (Exception ex)
{
WorkBenchUtil.showMessage("Error", ex.getMessage());
ex.printStackTrace();
}
}
private void chooseSourcesForCrossMappings() throws MapperException
{
chosenSources = new Vector<DataSource>();
// to avoid choosing more than one data source for any mapping set
Hashtable<String,XOReader> mappingSetsByURI = new Hashtable<String,XOReader>();
for (Iterator<DataSource> it = dataSourceView.getActiveDataSources().iterator(); it.hasNext();)
{
DataSource ds = it.next();
// happens once per mapping set; choose the first active data source per mapping set
if (mappingSetsByURI.get(ds.mappingSetURIString()) == null)
{
mappingSetsByURI.put(ds.mappingSetURIString(), ds.getReader());
chosenSources.add(ds);
}
}
}
private String activeCodes()
{
String codes = "";
for (int i = 0; i < chosenSources.size();i++)
{
String code = chosenSources.get(i).getCode();
codes = codes + code;
}
return codes;
}
private void makeHeaderRow()
{
int size = 3 + chosenSources.size();
String[] row = new String[size];
row[0] = "Association";
row[1] = "Class";
row[2] = "Property";
for (int i = 0; i < chosenSources.size();i++)
{
String code = chosenSources.get(i).getCode();
row[3 + i] = "XPath in source " + code;
}
mappingRows.add(row);
}
/**
* recursive descent of the mapped class model as far as there are mappings in any mapping set,
* writing rows of mapping XPaths to the csv file
* @param theClass
* @param subsets
*/
private void addMappingRows(String assocName, EClass theClass, String[] subsets)
{
String[] mappingRow = new String[3 + chosenSources.size()];
mappingRow[0] = assocName;
mappingRow[1] = ModelUtil.getQualifiedClassName(theClass);
// write a row for the object mappings
mappingRow[2] = "";
// write rows for the property mappings
// recursive descent through containment associations
}
}