blob: 0849e46d6b8859bbfc4471ed62af417b8b75b309 [file] [log] [blame]
/*****************************************************************************
* Copyright (c) 2017 CEA LIST and others.
*
* 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:
* Francois LE FEVRE (CEA) francois.le-fevre@cea.fr - Initial API and Implementation
*
*****************************************************************************/
package org.eclipse.papyrus.developer.migration.elementtypereference.common;
import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.apache.commons.io.FileUtils;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
/**
*
* Dedicated class to implement the generic strategy
*
*/
public abstract class AbstractElementTypeMigrationModel {
static String ELEMENTTYPESCONFIGURATIONS = new String("elementtypesconfigurations");
protected HashMap<String, ArrayList<String>> identifier2Id;
public AbstractElementTypeMigrationModel(String folderRootGit4ElementtypeData) {
identifier2Id = new HashMap<String, ArrayList<String>>();
parseDataModel(folderRootGit4ElementtypeData);
}
/**
* @param gitRootFolder
* the root folder where the tool can find any needed elementypeconfiguration files
* @return
*/
/**
* @param gitRootFolder
* @return
*/
private void parseDataModel(String gitRootFolder) {
try {
File folder = new File(gitRootFolder);
if (folder.isDirectory()) {
String[] extension = new String[] { ELEMENTTYPESCONFIGURATIONS };
List<File> files = (List<File>) FileUtils.listFiles(folder, extension, true);
for (File file : files) {
if (file.isFile()) {
System.err.println("Dealing with " + file.getAbsolutePath());
// Find the root folder of the plugin containng the elementtypeconfiguration file
File rootPlugin = getPluginRoot(file);
// Parsing the data
DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
Document doc = dBuilder.parse(file);
// optional, but recommended
// read this - http://stackoverflow.com/questions/13786607/normalization-in-dom-parsing-with-java-how-does-it-work
doc.getDocumentElement().normalize();
// Ensuring to add right header
Element root = doc.getDocumentElement();
if (root.getAttribute("xmlns:elementtypesconfigurations").length() == 0) {
root.setAttribute("xmlns:elementtypesconfigurations", "http://www.eclipse.org/papyrus/infra/elementtypesconfigurations/1.2");
}
NodeList nList = doc.getElementsByTagName("elementTypeConfigurations");
for (int temp = 0; temp < nList.getLength(); temp++) {
Node nNode = nList.item(temp);
if (nNode.getNodeType() == Node.ELEMENT_NODE) {
Element eElement = (Element) nNode;
if (identifier2Id.get(eElement.getAttribute("identifier")) == null && eElement.getAttribute("xmi:id") != null) {
ArrayList<String> a = new ArrayList<String>();
a.add(eElement.getAttribute("xmi:id"));
a.add(rootPlugin.getName() + file.getAbsolutePath().split(rootPlugin.getName())[1]);
a.add(eElement.getAttribute("xsi:type"));
identifier2Id.put(eElement.getAttribute("identifier"), a);// +"\t"+listOfFiles[i]);
} else {
System.err.println(eElement.getAttribute("identifier") + "\t" + eElement.getAttribute("xmi:id") + "\t" + file.getAbsolutePath() + " VERSUS " + eElement.getAttribute("identifier") + "\t"
+ identifier2Id.get(eElement.getAttribute("identifier")));
}
}
}
}
}
} else {
System.err.println("Root folder is not a directory, no elementtype data found:" + gitRootFolder);
}
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* Recursive function to find the plugin root by looking for the plugin.xml file or pom.xml or .project
*
* @param initialFile
* @return
*/
private File getPluginRoot(File initialFile) {
File f = initialFile.getParentFile();
String dir = new String(File.separator);
File lookFile;
if (f == null) {
String[] items = initialFile.getAbsolutePath().split(File.separator);
for (int i = 1; i < items.length - 1; i++) {
dir += items[i] + File.separator;
}
lookFile = new File(dir);
} else {
lookFile = f;
}
if (lookFile.isDirectory()) {
String[] extension = new String[] { "xml" };
List<File> files = (List<File>) FileUtils.listFiles(lookFile, extension, true);
for (File tmpFile : files) {
if (tmpFile.getName().equals("plugin.xml") || tmpFile.getName().equals("pom.xml") || tmpFile.getName().equals(".project")) {
System.err.println("found in " + lookFile.getAbsolutePath());
return lookFile;
}
}
return getPluginRoot(lookFile);
} else {
return null;
}
}
/**
* The method where the strategy to migrate the old model in the new model, have to be implemented by all model transformations
*
* @param rootFolder
* place to look for model files to migrate
* @param identifier2Id
* @param outputRootFolder
* if set to null, will replace the content of the initial files
* @return
*/
public abstract void migrateModelDocuments(String rootFolder, String outputRootFolder);
/**
* Model writing method
*
* @param doc
* @param file
* @param outputRootFolder
*/
protected static void exportDocument2File(Document doc, File file, String outputRootFolder) {
try {
final TransformerFactory transformerFactory = TransformerFactory.newInstance();
Transformer transformer;
transformer = transformerFactory.newTransformer();
transformer.setOutputProperty(OutputKeys.VERSION, "1.0");
transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
transformer.setOutputProperty(OutputKeys.STANDALONE, "yes");
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2");
final DOMSource source = new DOMSource(doc);
final StreamResult output;
// Code to display in file
File f;
if (outputRootFolder != null && outputRootFolder.length() != 0) {
f = new File(outputRootFolder + File.separator + file.getName());
} else {
f = new File(file.getAbsolutePath());
}
System.err.println("Output to " + f.getAbsolutePath());
output = new StreamResult(f);
// Code to export to console
// final StreamResult sortie = new StreamResult(System.out);
transformer.transform(source, output);
} catch (TransformerConfigurationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (TransformerException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}