/*
Violet - A program for editing UML diagrams.
Copyright (C) 2007 Cay S. Horstmann (http://horstmann.com)
Alexandre de Pellegrin (http://alexdp.free.fr);
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package com.horstmann.violet.framework.file.persistence;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import com.horstmann.violet.product.diagram.property.ArrowheadChoiceList;
import com.horstmann.violet.product.diagram.property.BentStyleChoiceList;
import com.horstmann.violet.product.diagram.property.LineStyleChoiceList;
import com.horstmann.violet.framework.util.StringFilterOutputStream;
import com.horstmann.violet.product.diagram.common.node.DiagramLinkNode;
import com.horstmann.violet.product.diagram.common.edge.NoteEdge;
import com.horstmann.violet.product.diagram.common.node.NoteNode;
import com.horstmann.violet.product.diagram.common.node.PointNode;
/**
* This class provides file format services
*
* @author Alexandre de Pellegrin
*
*/
public class Violet016BackportFormatService
{
/**
* This filter guarantees compatibility for Violet 0.16 file format
*
* @param in raw input stream
* @return converted input stream
*/
public static InputStream convertFromViolet016(InputStream in)
{
Map<String, String> replaceMap = new Hashtable<String, String>();
replaceMap.putAll(violet016CompatibilityMap);
// fix framework elements
replaceMap.put("com.horstmann.violet.BentStyleChoiceList", BentStyleChoiceList.class.getName());
replaceMap.put("com.horstmann.violet.LineStyleChoiceList", LineStyleChoiceList.class.getName());
replaceMap.put("com.horstmann.violet.ArrowheadChoiceList", ArrowheadChoiceList.class.getName());
// fix common elements package
replaceMap.put("com.horstmann.violet.DiagramLinkNode", DiagramLinkNode.class.getName());
replaceMap.put("com.horstmann.violet.NoteEdge", NoteEdge.class.getName());
replaceMap.put("com.horstmann.violet.NoteNode", NoteNode.class.getName());
replaceMap.put("com.horstmann.violet.PointNode", PointNode.class.getName());
String original = getInputStreamContent(in);
String replaced = replaceAll(original, replaceMap);
try
{
return new ByteArrayInputStream(replaced.getBytes("UTF-8"));
}
catch (UnsupportedEncodingException ex)
{
ex.printStackTrace();
return new ByteArrayInputStream(replaced.getBytes());
}
}
/**
* Converts inputStream to String
*
* @param in stream
* @return string
*/
private static String getInputStreamContent(InputStream in)
{
try
{
InputStreamReader isr = new InputStreamReader(in, "UTF-8");
StringBuffer buffer = new StringBuffer();
int len = 1024;
char buf[] = new char[len];
int numRead;
while ((numRead = isr.read(buf, 0, len)) != -1)
{
buffer.append(buf, 0, numRead);
}
isr.close();
return buffer.toString();
}
catch (IOException e)
{
throw new RuntimeException(e);
}
}
/**
* Filters a string and replaces all key courrences issed from the map by its valye
*
* @param input string
* @param replaceMap key = searchedString / value = replaceString
* @return filtered string
*/
private static String replaceAll(String input, Map<String, String> replaceMap)
{
Set<String> set = replaceMap.keySet();
for (Iterator<String> iter = set.iterator(); iter.hasNext();)
{
String searchedStr = iter.next();
String replaceStr = replaceMap.get(searchedStr);
input = input.replaceAll(searchedStr, replaceStr);
}
return input;
}
/**
* This filter guarantees compatibility for Violet 0.16 file format
*
* @param out raw output stream
* @return converted output stream
*/
public static OutputStream convertToViolet016(OutputStream out)
{
Map<String, String> replaceMap = new Hashtable<String, String>();
replaceMap.putAll(getReversedMap(violet016CompatibilityMap));
// fix framework elements
replaceMap.put(BentStyleChoiceList.class.getName(), "com.horstmann.violet.BentStyleChoiceList");
replaceMap.put(LineStyleChoiceList.class.getName(), "com.horstmann.violet.LineStyleChoiceList");
replaceMap.put(ArrowheadChoiceList.class.getName(), "com.horstmann.violet.ArrowheadChoiceList");
// fix common elements package
replaceMap.put(DiagramLinkNode.class.getName(), "com.horstmann.violet.DiagramLinkNode");
replaceMap.put(NoteEdge.class.getName(), "com.horstmann.violet.NoteEdge");
replaceMap.put(NoteNode.class.getName(), "com.horstmann.violet.NoteNode");
replaceMap.put(PointNode.class.getName(), "com.horstmann.violet.PointNode");
StringFilterOutputStream filteredOutputStream = new StringFilterOutputStream(out, replaceMap);
return filteredOutputStream;
}
/**
* Registers new keys/values to keep Violet 0.16 compatibility. Keys are Violet 0.16 strings. Map values are real values
* corresponding to their old Violet 0.16 string.
*
* @param entries
*/
public static void addViolet016CompatibilityEntries(Map<String, String> entries)
{
violet016CompatibilityMap.putAll(entries);
}
/**
* Reverse a map. Be carefull to have unique values as they will become keys!
*
* @param mapToReverse
* @return
*/
private static Map<String, String> getReversedMap(Map<String, String> mapToReverse)
{
Map<String, String> result = new HashMap<String, String>();
for (String aKey : mapToReverse.keySet())
{
String aValue = mapToReverse.get(aKey);
if (aValue != null && !result.containsKey(aValue))
{
result.put(aValue, aKey);
}
}
return result;
}
/**
* Violet 0.16 compatibility map . Keys are Violet 0.16 strings. Map values are real values corresponding to their old Violet
* 0.16 text.
*/
private static Map<String, String> violet016CompatibilityMap = new HashMap<String, String>();
}