blob: 9045334b047f1ecff980a1b1bfc5f4273b43ea3e [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2009, 2013 Borland Software Corporation 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:
* Alex Paperno
*******************************************************************************/
package org.eclipse.m2m.internal.qvt.oml.stdlib;
import org.eclipse.emf.ecore.EClassifier;
import org.eclipse.emf.ecore.EDataType;
import org.eclipse.emf.ecore.EDataType.Internal.ConversionDelegate;
import org.eclipse.m2m.qvt.oml.ecore.ImperativeOCL.DictionaryType;
import org.eclipse.m2m.qvt.oml.util.Dictionary;
import org.eclipse.m2m.qvt.oml.util.Utils;
/**
* @since 3.4
*/
public class ConversionDictionary implements ConversionDelegate {
final private DictionaryType fMyType;
public ConversionDictionary(DictionaryType type) {
this.fMyType = type;
}
public String convertToString(Object value) {
EClassifier keyType = fMyType.getKeyType();
EClassifier elementType = fMyType.getElementType();
if (!(value instanceof Dictionary<?, ?>)
|| !(keyType instanceof EDataType)
|| !(elementType instanceof EDataType)) {
return ""; //$NON-NLS-1$
}
// support nested declarations
ConversionUtils.setupConversionDelegate(keyType);
ConversionUtils.setupConversionDelegate(elementType);
StringBuilder result = new StringBuilder();
@SuppressWarnings("unchecked")
Dictionary<Object, Object> dictionary = (Dictionary<Object, Object>)value;
for (Object key : dictionary.keys()) {
if (result.length() > 0) {
result.append(", "); //$NON-NLS-1$
}
String data = keyType.getEPackage().getEFactoryInstance().convertToString((EDataType)keyType, key);
if (ConversionUtils.isStringType(keyType)) {
data = escapeDictionaryElem(data);
}
result.append(data);
result.append("="); //$NON-NLS-1$
data = elementType.getEPackage().getEFactoryInstance().convertToString((EDataType)elementType, dictionary.get(key));
if (ConversionUtils.isStringType(elementType)) {
data = escapeDictionaryElem(data);
}
result.append(data);
}
return result.insert(0, "[").append("]").toString(); //$NON-NLS-1$ //$NON-NLS-2$
}
public Object createFromString(String literal) {
EClassifier keyType = fMyType.getKeyType();
EClassifier elementType = fMyType.getElementType();
if (!(keyType instanceof EDataType)) {
throw new IllegalArgumentException("Invalid datatype: " + keyType.getName()); //$NON-NLS-1$
}
if (!(elementType instanceof EDataType)) {
throw new IllegalArgumentException("Invalid datatype: " + elementType.getName()); //$NON-NLS-1$
}
literal = literal.trim();
if (literal.length() > 0 && literal.charAt(0) == '[') {
if (literal.charAt(literal.length()-1) != ']') {
throw new IllegalArgumentException("Invalid datatype: " + elementType.getName()); //$NON-NLS-1$
}
literal = literal.substring(1, literal.length()-1);
}
// support nested declarations
ConversionUtils.setupConversionDelegate(keyType);
ConversionUtils.setupConversionDelegate(elementType);
Dictionary<Object, Object> result = Utils.createDictionary();
for (int i = 0; i < literal.length(); ++i) {
int endIndex = extractDictionaryKey(literal, i);
Object key = ConversionUtils.createFromString(keyType, ConversionCollection.unescapeString(literal.substring(i, endIndex)).trim());
i = endIndex+1;
endIndex = extractDictionaryValue(literal, i);
Object value = ConversionUtils.createFromString(elementType, ConversionCollection.unescapeString(literal.substring(i, endIndex)).trim());
i = endIndex;
result.put(key, value);
}
return result;
}
private static String escapeDictionaryElem(String literal) {
StringBuilder result = new StringBuilder(literal.length());
for (int i = 0; i < literal.length(); ++i) {
char ch = literal.charAt(i);
switch (ch) {
case '\\':
case ',':
case '=':
case '[':
case ']':
result.append('\\');
default:
result.append(ch);
}
}
return result.toString();
}
private static int extractDictionaryKey(String literal, int startIndex) {
int level = 0;
for (int i = startIndex; i < literal.length(); ++i) {
switch (literal.charAt(i)) {
case '\\':
++i;
break;
case '[':
++level;
break;
case ']':
--level;
break;
case '=':
if (level == 0) {
return i;
}
break;
}
}
throw new IllegalArgumentException("Invalid dictionary key: " + literal.substring(startIndex)); //$NON-NLS-1$
}
private static int extractDictionaryValue(String literal, int startIndex) {
int level = 0;
for (int i = startIndex; i < literal.length(); ++i) {
switch (literal.charAt(i)) {
case '\\':
++i;
break;
case '[':
++level;
break;
case ']':
--level;
break;
case ',':
if (level == 0) {
return i;
}
break;
}
}
return literal.length();
}
}