/******************************************************************************* | |
* Copyright (c) 2014 Hussein Mhanna | |
* | |
* All rights reserved. This program and the accompanying materials | |
* are made available under the terms of the Eclipse Public License v1.0 | |
* which accompanies this distribution, and is available at | |
* http://www.eclipse.org/legal/epl-v10.html | |
* | |
* Contributors: | |
* Hussein Mhanna - initial API and implementation | |
******************************************************************************/ | |
package org.eclipse.rmf.reqif10.csv.importer.utils; | |
import java.io.File; | |
import java.io.FileReader; | |
import java.io.IOException; | |
import java.util.Arrays; | |
import java.util.Collection; | |
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.emf.common.command.Command; | |
import org.eclipse.emf.common.command.CompoundCommand; | |
import org.eclipse.emf.common.util.EList; | |
import org.eclipse.emf.common.util.URI; | |
import org.eclipse.emf.ecore.EAttribute; | |
import org.eclipse.emf.ecore.EStructuralFeature; | |
import org.eclipse.emf.ecore.resource.Resource; | |
import org.eclipse.emf.ecore.util.EcoreUtil; | |
import org.eclipse.emf.edit.command.AddCommand; | |
import org.eclipse.emf.edit.command.CommandParameter; | |
import org.eclipse.emf.edit.command.CreateChildCommand; | |
import org.eclipse.emf.edit.domain.AdapterFactoryEditingDomain; | |
import org.eclipse.emf.edit.domain.EditingDomain; | |
import org.eclipse.emf.edit.provider.ComposedAdapterFactory; | |
import org.eclipse.rmf.reqif10.AttributeDefinition; | |
import org.eclipse.rmf.reqif10.AttributeDefinitionBoolean; | |
import org.eclipse.rmf.reqif10.AttributeDefinitionDate; | |
import org.eclipse.rmf.reqif10.AttributeDefinitionEnumeration; | |
import org.eclipse.rmf.reqif10.AttributeDefinitionInteger; | |
import org.eclipse.rmf.reqif10.AttributeDefinitionReal; | |
import org.eclipse.rmf.reqif10.AttributeDefinitionString; | |
import org.eclipse.rmf.reqif10.AttributeDefinitionXHTML; | |
import org.eclipse.rmf.reqif10.AttributeValue; | |
import org.eclipse.rmf.reqif10.AttributeValueEnumeration; | |
import org.eclipse.rmf.reqif10.AttributeValueXHTML; | |
import org.eclipse.rmf.reqif10.DatatypeDefinition; | |
import org.eclipse.rmf.reqif10.DatatypeDefinitionBoolean; | |
import org.eclipse.rmf.reqif10.DatatypeDefinitionDate; | |
import org.eclipse.rmf.reqif10.DatatypeDefinitionEnumeration; | |
import org.eclipse.rmf.reqif10.DatatypeDefinitionInteger; | |
import org.eclipse.rmf.reqif10.DatatypeDefinitionReal; | |
import org.eclipse.rmf.reqif10.DatatypeDefinitionString; | |
import org.eclipse.rmf.reqif10.DatatypeDefinitionXHTML; | |
import org.eclipse.rmf.reqif10.EnumValue; | |
import org.eclipse.rmf.reqif10.ReqIF; | |
import org.eclipse.rmf.reqif10.ReqIF10Factory; | |
import org.eclipse.rmf.reqif10.ReqIF10Package; | |
import org.eclipse.rmf.reqif10.SpecHierarchy; | |
import org.eclipse.rmf.reqif10.SpecObject; | |
import org.eclipse.rmf.reqif10.SpecObjectType; | |
import org.eclipse.rmf.reqif10.SpecType; | |
import org.eclipse.rmf.reqif10.Specification; | |
import org.eclipse.rmf.reqif10.XhtmlContent; | |
import org.eclipse.rmf.reqif10.common.util.ProrXhtmlSimplifiedHelper; | |
import org.eclipse.rmf.reqif10.common.util.ReqIF10Util; | |
import org.eclipse.rmf.reqif10.csv.importer.mapping.DataType; | |
import org.eclipse.rmf.reqif10.csv.importer.mapping.MappingItem; | |
import org.eclipse.rmf.reqif10.csv.importer.mapping.MappingLibrary; | |
import org.eclipse.rmf.reqif10.xhtml.XhtmlDivType; | |
import au.com.bytecode.opencsv.CSVReader; | |
public class Importer { | |
private static final ReqIF10Factory FACTORY = ReqIF10Factory.eINSTANCE; | |
private EditingDomain editingDomain; | |
private String path; | |
private MappingLibrary library; | |
private ReqIF reqIf; | |
private char separator; | |
private boolean header; | |
private CompoundCommand compoundCommand; | |
private Map<String, AttributeDefinition> attributeDefinitionMap; | |
public Importer(EditingDomain editingDomain, String path, | |
MappingLibrary library, ReqIF reqIf, char separator, boolean header) { | |
super(); | |
this.editingDomain = editingDomain; | |
this.path = path; | |
this.library = library; | |
this.reqIf = reqIf; | |
this.separator = separator; | |
this.header = header; | |
attributeDefinitionMap = new HashMap<String, AttributeDefinition>(); | |
} | |
public static void importReq(EditingDomain editingDomain, IFile file, | |
String path, MappingLibrary library, char separator, boolean header) | |
throws IOException { | |
boolean needDispose = false; | |
if (editingDomain == null) { | |
URI uri = URI.createPlatformResourceURI(file.getFullPath() | |
.toOSString(), true); | |
editingDomain = Utils.createReqIFEditingDomain(); | |
editingDomain.getResourceSet().getResource(uri, true); | |
needDispose = true; | |
} | |
ReqIF reqIf = (ReqIF) editingDomain.getResourceSet().getResources() | |
.get(0).getContents().get(0); | |
Importer importer = new Importer(editingDomain, path, library, reqIf, | |
separator, header); | |
importer.doImportReq(); | |
if (needDispose) { | |
ComposedAdapterFactory adapterFactory = (ComposedAdapterFactory) ((AdapterFactoryEditingDomain) editingDomain) | |
.getAdapterFactory(); | |
adapterFactory.dispose(); | |
EList<Resource> resources = editingDomain.getResourceSet() | |
.getResources(); | |
final Map<Object, Object> saveOptions = new HashMap<Object, Object>(); | |
saveOptions.put(Resource.OPTION_SAVE_ONLY_IF_CHANGED, | |
Resource.OPTION_SAVE_ONLY_IF_CHANGED_MEMORY_BUFFER); | |
for (Resource resource : resources) { | |
resource.save(saveOptions); | |
resource.unload(); | |
resource.getContents().clear(); | |
} | |
} | |
} | |
public void doImportReq() throws IOException { | |
CSVReader reader = new CSVReader(new FileReader(path), separator); | |
Map<Short, String> map = null; | |
if (header) { | |
String[] headerNames = reader.readNext(); | |
map = buildMappingMap(library, Arrays.asList(headerNames)); | |
} else { | |
map = buildMappingMap(library); | |
} | |
compoundCommand = new CompoundCommand(); | |
importReq(reader, map, library.getItems()); | |
editingDomain.getCommandStack().execute(compoundCommand); | |
compoundCommand = null; | |
attributeDefinitionMap.clear(); | |
} | |
protected void importReq(CSVReader reader, Map<Short, String> map, | |
List<MappingItem> mappingItems) throws IOException { | |
Specification specification = reqIf.getCoreContent() | |
.getSpecifications().get(0); | |
SpecObjectType specObjectType = getSpecObjectType(mappingItems, | |
getSpecTypeName()); | |
String[] nextLine; | |
while ((nextLine = reader.readNext()) != null) { | |
Command command = CreateChildCommand.create(editingDomain, | |
specification, new CommandParameter(specification, | |
ReqIF10Package.Literals.SPECIFICATION__CHILDREN, | |
specObjectType), Collections | |
.singleton(specification)); | |
compoundCommand.appendAndExecute(command); | |
Collection<?> result = command.getResult(); | |
for (Object object : result) { | |
if (object instanceof SpecHierarchy) { | |
SpecObject specObject = ((SpecHierarchy) object) | |
.getObject(); | |
createAttributeValues(specObject); | |
for (int i = 0; i < nextLine.length; i++) { | |
String attributeName = map.get((short) i); | |
String attributeStringValue = nextLine[i]; | |
if (attributeName != null) { | |
EAttribute attribute = getSpecObjectAttribute(attributeName); | |
if (attribute != null) { | |
specObject.eSet(attribute, EcoreUtil | |
.createFromString( | |
attribute.getEAttributeType(), | |
attributeStringValue)); | |
} else { | |
AttributeDefinition attributeDefinition = attributeDefinitionMap | |
.get(attributeName); | |
AttributeValue attributeValue = ReqIF10Util | |
.getAttributeValue(specObject, | |
attributeDefinition); | |
if (attributeValue != null) { | |
if (attributeValue instanceof AttributeValueEnumeration) { | |
EnumValue enumValue = getEnumValue( | |
(AttributeDefinitionEnumeration) attributeDefinition, | |
attributeStringValue); | |
ReqIF10Util.setTheValue(attributeValue, | |
Collections | |
.singleton(enumValue)); | |
} else if (attributeValue instanceof AttributeValueXHTML) { | |
AttributeValueXHTML attributeValueXHTML = (AttributeValueXHTML) attributeValue; | |
// The formatted text is edited | |
XhtmlDivType div = ProrXhtmlSimplifiedHelper | |
.stringToSimplifiedXhtml(attributeStringValue); | |
XhtmlContent origTheValue = attributeValueXHTML | |
.getTheValue(); | |
if (origTheValue == null) { | |
origTheValue = ReqIF10Factory.eINSTANCE | |
.createXhtmlContent(); | |
attributeValueXHTML | |
.setTheValue(origTheValue); | |
} | |
if (!attributeValueXHTML.isSimplified()) { | |
boolean formattedAttribute = ProrXhtmlSimplifiedHelper | |
.isFormattedAttribute(origTheValue); | |
if (formattedAttribute) { | |
attributeValueXHTML | |
.setSimplified(true); | |
} | |
} | |
origTheValue.setXhtml(div); | |
} else { | |
EAttribute eAttribute = (EAttribute) ReqIF10Util | |
.getTheValueFeature(attributeValue); | |
ReqIF10Util | |
.setTheValue( | |
attributeValue, | |
EcoreUtil | |
.createFromString( | |
eAttribute | |
.getEAttributeType(), | |
attributeStringValue)); | |
} | |
} | |
} | |
} | |
} | |
} | |
} | |
} | |
reader.close(); | |
} | |
private void createAttributeValues(SpecObject specObject) { | |
EList<AttributeDefinition> attributeDefinitions = specObject.getType() | |
.getSpecAttributes(); | |
for (AttributeDefinition attributeDefinition : attributeDefinitions) { | |
specObject.getValues().add( | |
ReqIF10Util.createAttributeValue(attributeDefinition)); | |
} | |
} | |
private EnumValue getEnumValue( | |
AttributeDefinitionEnumeration attributeDefinition, | |
String attributeStringValue) { | |
EList<EnumValue> values = attributeDefinition.getType() | |
.getSpecifiedValues(); | |
for (EnumValue enumValue : values) { | |
if ((enumValue.getLongName() != null) | |
&& (enumValue.getLongName().equals(attributeStringValue))) { | |
return enumValue; | |
} | |
} | |
// Create the attribute value and return it | |
EnumValue enumValue = FACTORY.createEnumValue(); | |
enumValue.setLongName(attributeStringValue); | |
values.add(enumValue); | |
return enumValue; | |
} | |
protected SpecObjectType getSpecObjectType(List<MappingItem> mappingItems, | |
String specTypeName) { | |
EList<SpecType> specTypes = reqIf.getCoreContent().getSpecTypes(); | |
for (SpecType specType : specTypes) { | |
if (specType instanceof SpecObjectType) { | |
SpecObjectType specObjectType = (SpecObjectType) specType; | |
if (containsAttributeDefinitions(specObjectType, mappingItems, | |
specTypeName)) { | |
fillAttributeDefinitionMap(specObjectType); | |
return specObjectType; | |
} | |
} | |
} | |
return createSpecObjectType(mappingItems, specTypeName); | |
} | |
private void fillAttributeDefinitionMap(SpecObjectType specObjectType) { | |
EList<AttributeDefinition> attributeDefinitions = specObjectType | |
.getSpecAttributes(); | |
for (AttributeDefinition attributeDefinition : attributeDefinitions) { | |
attributeDefinitionMap.put(attributeDefinition.getLongName(), | |
attributeDefinition); | |
} | |
} | |
private boolean containsAttributeDefinitions(SpecObjectType specObjectType, | |
List<MappingItem> mappingItems, String specTypeName) { | |
if ((specObjectType.getLongName() == null) | |
|| (false == specObjectType.getLongName().equals(specTypeName))) { | |
return false; | |
} | |
if (mappingItems.size() != specObjectType.getSpecAttributes().size()) { | |
return false; | |
} | |
for (MappingItem mappingItem : mappingItems) { | |
if (false == containsAttributeDefinition(specObjectType, | |
mappingItem)) { | |
return false; | |
} | |
} | |
return true; | |
} | |
private boolean containsAttributeDefinition(SpecObjectType specObjectType, | |
MappingItem item) { | |
boolean found = false; | |
EList<AttributeDefinition> attributeDefinitions = specObjectType | |
.getSpecAttributes(); | |
for (AttributeDefinition attributeDefinition : attributeDefinitions) { | |
if ((attributeDefinition.getLongName() != null) | |
&& (attributeDefinition.getLongName().equals(item | |
.getAttributeName()))) { | |
switch (item.getDataType()) { | |
case BOOLEAN: | |
found = attributeDefinition instanceof AttributeDefinitionBoolean; | |
break; | |
case INTEGER: | |
found = attributeDefinition instanceof AttributeDefinitionInteger; | |
break; | |
case REAL: | |
found = attributeDefinition instanceof AttributeDefinitionReal; | |
break; | |
case DATE: | |
found = attributeDefinition instanceof AttributeDefinitionDate; | |
break; | |
case XHTML: | |
found = attributeDefinition instanceof AttributeDefinitionXHTML; | |
break; | |
case ENUMERATION: | |
found = attributeDefinition instanceof AttributeDefinitionEnumeration; | |
break; | |
case STRING: | |
default: | |
found = attributeDefinition instanceof AttributeDefinitionString; | |
break; | |
} | |
if (found) { | |
break; | |
} | |
} | |
} | |
return found; | |
} | |
protected SpecObjectType createSpecObjectType( | |
List<MappingItem> mappingItems, String specTypeName) { | |
SpecObjectType specObjectType = FACTORY.createSpecObjectType(); | |
specObjectType.setLongName(specTypeName); | |
for (MappingItem mappingItem : mappingItems) { | |
String attributeName = mappingItem.getAttributeName(); | |
if (getSpecObjectAttribute(attributeName) == null) { | |
DatatypeDefinition datatypeDefinition = createDatatypeDefinition( | |
mappingItem.getDataType(), attributeName); | |
Command command = AddCommand.create(editingDomain, | |
reqIf.getCoreContent(), | |
ReqIF10Package.Literals.REQ_IF_CONTENT__DATATYPES, | |
Collections.singleton(datatypeDefinition)); | |
compoundCommand.appendAndExecute(command); | |
AttributeDefinition attributeDefinition = createAttributeDefinition( | |
datatypeDefinition, attributeName); | |
attributeDefinition.setLongName(attributeName); | |
specObjectType.getSpecAttributes().add(attributeDefinition); | |
} | |
} | |
Command specTypecommand = AddCommand.create(editingDomain, | |
reqIf.getCoreContent(), | |
ReqIF10Package.Literals.REQ_IF_CONTENT__SPEC_TYPES, | |
Collections.singleton(specObjectType)); | |
compoundCommand.appendAndExecute(specTypecommand); | |
fillAttributeDefinitionMap(specObjectType); | |
return specObjectType; | |
} | |
protected AttributeDefinition createAttributeDefinition( | |
DatatypeDefinition datatypeDefinition, String name) { | |
AttributeDefinition attributeDefinition = null; | |
if (datatypeDefinition instanceof DatatypeDefinitionBoolean) { | |
attributeDefinition = FACTORY.createAttributeDefinitionBoolean(); | |
((AttributeDefinitionBoolean) attributeDefinition) | |
.setType((DatatypeDefinitionBoolean) datatypeDefinition); | |
} else if (datatypeDefinition instanceof DatatypeDefinitionInteger) { | |
attributeDefinition = FACTORY.createAttributeDefinitionInteger(); | |
((AttributeDefinitionInteger) attributeDefinition) | |
.setType((DatatypeDefinitionInteger) datatypeDefinition); | |
} else if (datatypeDefinition instanceof DatatypeDefinitionReal) { | |
attributeDefinition = FACTORY.createAttributeDefinitionReal(); | |
((AttributeDefinitionReal) attributeDefinition) | |
.setType((DatatypeDefinitionReal) datatypeDefinition); | |
} else if (datatypeDefinition instanceof DatatypeDefinitionDate) { | |
attributeDefinition = FACTORY.createAttributeDefinitionDate(); | |
((AttributeDefinitionDate) attributeDefinition) | |
.setType((DatatypeDefinitionDate) datatypeDefinition); | |
} else if (datatypeDefinition instanceof DatatypeDefinitionXHTML) { | |
attributeDefinition = FACTORY.createAttributeDefinitionXHTML(); | |
((AttributeDefinitionXHTML) attributeDefinition) | |
.setType((DatatypeDefinitionXHTML) datatypeDefinition); | |
} else if (datatypeDefinition instanceof DatatypeDefinitionEnumeration) { | |
attributeDefinition = FACTORY | |
.createAttributeDefinitionEnumeration(); | |
((AttributeDefinitionEnumeration) attributeDefinition) | |
.setType((DatatypeDefinitionEnumeration) datatypeDefinition); | |
} else { | |
attributeDefinition = FACTORY.createAttributeDefinitionString(); | |
((AttributeDefinitionString) attributeDefinition) | |
.setType((DatatypeDefinitionString) datatypeDefinition); | |
} | |
attributeDefinition.setLongName(name); | |
return attributeDefinition; | |
} | |
protected DatatypeDefinition createDatatypeDefinition(DataType dataType, | |
String name) { | |
DatatypeDefinition dataTypeDefinition = null; | |
switch (dataType) { | |
case BOOLEAN: | |
dataTypeDefinition = FACTORY.createDatatypeDefinitionBoolean(); | |
break; | |
case INTEGER: | |
dataTypeDefinition = FACTORY.createDatatypeDefinitionInteger(); | |
break; | |
case REAL: | |
dataTypeDefinition = FACTORY.createDatatypeDefinitionReal(); | |
break; | |
case DATE: | |
dataTypeDefinition = FACTORY.createDatatypeDefinitionDate(); | |
break; | |
case XHTML: | |
dataTypeDefinition = FACTORY.createDatatypeDefinitionXHTML(); | |
break; | |
case ENUMERATION: | |
dataTypeDefinition = FACTORY.createDatatypeDefinitionEnumeration(); | |
break; | |
case STRING: | |
default: | |
dataTypeDefinition = FACTORY.createDatatypeDefinitionString(); | |
break; | |
} | |
dataTypeDefinition.setLongName(name); | |
return dataTypeDefinition; | |
} | |
protected EAttribute getSpecObjectAttribute(String attributeName) { | |
EStructuralFeature feature = ReqIF10Package.Literals.SPEC_OBJECT | |
.getEStructuralFeature(attributeName); | |
if (feature instanceof EAttribute) { | |
return (EAttribute) feature; | |
} | |
return null; | |
} | |
protected Map<Short, String> buildMappingMap(MappingLibrary library) { | |
List<MappingItem> items = library.getItems(); | |
Map<Short, String> map = new HashMap<Short, String>(items.size()); | |
for (MappingItem columnIndexMappingItem : items) { | |
map.put(Short.valueOf(columnIndexMappingItem.getColumnId()), | |
columnIndexMappingItem.getAttributeName()); | |
} | |
return map; | |
} | |
protected Map<Short, String> buildMappingMap(MappingLibrary library, | |
List<String> columnNames) { | |
List<MappingItem> items = library.getItems(); | |
Map<Short, String> map = new HashMap<Short, String>(items.size()); | |
for (MappingItem columnNameMappingItem : items) { | |
String columnName = columnNameMappingItem.getColumnId(); | |
short columnIndex = (short) columnNames.indexOf(columnName); | |
if (columnIndex != -1) { | |
map.put(columnIndex, columnNameMappingItem.getAttributeName()); | |
} | |
} | |
return map; | |
} | |
protected String getSpecTypeName() { | |
return path.substring(path.lastIndexOf(File.separator) + 1, | |
path.lastIndexOf('.')); | |
} | |
} |