| /***************************************************************************** |
| * 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(); |
| } |
| } |
| |
| } |