blob: 9e583b4edd83a08668b4a49bf786448459928eec [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2004, 2006 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.emf.emfatic.core.util;
import java.util.Hashtable;
import org.eclipse.emf.ecore.EcorePackage;
import org.eclipse.emf.ecore.util.ExtendedMetaData;
import org.eclipse.emf.emfatic.core.generator.ecore.EmfaticSemanticWarning;
import org.eclipse.emf.emfatic.core.generator.ecore.GenerationPhase;
import org.eclipse.emf.emfatic.core.lang.gen.ast.KeyEqualsValue;
/**
*
* @author cjdaly@us.ibm.com
*/
public class EmfaticAnnotationMap {
//
// values for special @namespace faux annotation
//
public static final String EPACKAGE_NAMESPACE_ANNOTATION = "namespace";
public static final String EPACKAGE_NSPREFIX_KEY = "prefix";
public static final String EPACKAGE_NSURI_KEY = "uri";
//
//
public static final String EMFATIC_ANNOTATION_MAP_LABEL = "EmfaticAnnotationMap";
public static final String EMFATIC_ANNOTATION_MAP_NS_URI = "http://www.eclipse.org/emf/2004/" + EMFATIC_ANNOTATION_MAP_LABEL;
// TODO: copied from EcoreUtil protected member. Is this in a public place?
private static final String GEN_MODEL_PACKAGE_LABEL = "GenModel";
private static final String GEN_MODEL_PACKAGE_NS_URI = "http://www.eclipse.org/emf/2002/GenModel";
private static final String ECORE_PACKAGE_LABEL = "Ecore";
private static final String EXTENDED_META_DATA_LABEL = "ExtendedMetaData";
//
//
//
private Hashtable<String, String> _keyToSourceURI;
private Hashtable<String, SourceURIDetails> _sourceURIToDetails;
public EmfaticAnnotationMap() {
_keyToSourceURI = new Hashtable<String, String>();
_sourceURIToDetails = new Hashtable<String, SourceURIDetails>();
initPredefinedMappings();
}
private void initPredefinedMappings() {
addMapping(GEN_MODEL_PACKAGE_LABEL, GEN_MODEL_PACKAGE_NS_URI);
addMapping(ECORE_PACKAGE_LABEL, EcorePackage.eNS_URI);
addMapping(EXTENDED_META_DATA_LABEL, ExtendedMetaData.ANNOTATION_URI);
addMapping(EMFATIC_ANNOTATION_MAP_LABEL, EMFATIC_ANNOTATION_MAP_NS_URI);
}
public String addMapping(String labelDecl, String sourceURI) {
return addMapping(labelDecl, sourceURI, null, null);
}
public String addMapping(String labelDecl, String sourceURI, KeyEqualsValue keyEqualsValue, GenerationPhase reporter) {
LabelMapping labelMapping = new LabelMapping(labelDecl);
if (!labelMapping.isWellFormed()) {
reportAddMappingProblem("label not well formed!", keyEqualsValue, reporter);
return null;
}
String label = labelMapping.getLabel();
String key = labelMapping.getKey();
if (sourceURI == null) sourceURI = label;
boolean newSourceURI = false;
SourceURIDetails details = (SourceURIDetails)_sourceURIToDetails.get(sourceURI);
if (details == null) {
details = new SourceURIDetails(sourceURI);
newSourceURI = true;
}
if (details.hasMapping(labelMapping.getImplicitKeyCount())) {
String m2 = details.getMapping(labelMapping.getImplicitKeyCount()).toString();
reportAddMappingProblem("mapping already exists: " + m2, keyEqualsValue, reporter);
return null;
}
String sourceURICheck = (String)_keyToSourceURI.get(key);
if (sourceURICheck == null) {
_keyToSourceURI.put(key, sourceURI);
}
else if (!sourceURICheck.equals(sourceURI)) {
reportAddMappingProblem("label aready in use for sourceURI: " + sourceURICheck, keyEqualsValue, reporter);
return null;
}
if (newSourceURI) {
_sourceURIToDetails.put(sourceURI, details);
}
details.addMapping(labelMapping);
return label;
}
private void reportAddMappingProblem(String message, KeyEqualsValue keyEqualsValue, GenerationPhase reporter) {
if ((keyEqualsValue != null) && (reporter != null)) {
reporter.logWarning(new EmfaticSemanticWarning.AnnotationMappingProblem(keyEqualsValue, message));
}
}
public String getLabelForSourceURI(String sourceURI, int paramCount) {
SourceURIDetails details = (SourceURIDetails)_sourceURIToDetails.get(sourceURI);
if (details == null) return null;
LabelMapping labelMapping = details.getMapping(paramCount);
if (labelMapping != null) return labelMapping.getLabel();
// See if there's a "default" label
labelMapping = details.getMapping(0);
if (labelMapping != null) return labelMapping.getLabel();
return null;
}
public String mapSourceURI(String literalSourceUriText) {
return (String)_keyToSourceURI.get(literalSourceUriText.toLowerCase());
}
public String getImplicitKeyName(String sourceURI, int paramIndex, int totalParamCount) {
SourceURIDetails details = (SourceURIDetails)_sourceURIToDetails.get(sourceURI);
if (details == null) return null;
LabelMapping labelMapping = details.getMapping(totalParamCount);
if (labelMapping == null) return null;
return labelMapping.getImplicitKey(paramIndex);
}
private static class SourceURIDetails {
private String _sourceURI;
private Hashtable<Integer, LabelMapping> _keyCountToLabelMapping;
public SourceURIDetails(String sourceURI) {
_sourceURI = sourceURI;
_keyCountToLabelMapping = new Hashtable<Integer, LabelMapping>();
}
public String getSourceURI() {
return _sourceURI;
}
public LabelMapping addMapping(LabelMapping mapping) {
Integer keyCount = new Integer(mapping.getImplicitKeyCount());
_keyCountToLabelMapping.put(keyCount, mapping);
return mapping;
}
public LabelMapping getMapping(int keyCount) {
Integer keyCountInt = new Integer(keyCount);
LabelMapping mapping = (LabelMapping)_keyCountToLabelMapping.get(keyCountInt);
return mapping;
}
public boolean hasMapping(String label, int keyCount) {
LabelMapping mapping = getMapping(keyCount);
if (mapping == null) return false;
return mapping.getKey().equals(label.toLowerCase());
}
public boolean hasMapping(int keyCount) {
LabelMapping mapping = getMapping(keyCount);
return mapping != null;
}
}
private static class LabelMapping {
private String _origLabel;
private String _label;
private String[] _implicitKeys;
private boolean _isWellFormed = true;
public LabelMapping(String label) {
_origLabel = label;
try {
init(label);
}
catch (Exception ex) {
_isWellFormed = false;
}
}
private void init(String label) {
int lParenPos = label.indexOf('(');
if (lParenPos == -1) {
_label = label;
_implicitKeys = new String[0];
}
else {
String implicitKeyText = label.substring(lParenPos+1, label.length());
_label = label.substring(0, lParenPos);
implicitKeyText = implicitKeyText.replace(')', ' ');
_implicitKeys = implicitKeyText.split(",");
for (int i = 0; i < _implicitKeys.length; i++) {
String implicitKey = _implicitKeys[i].trim();
if ((implicitKey == null) || ("".equals(implicitKey))) {
_implicitKeys[i] = "_undef" + Integer.toString(i);
_isWellFormed = false;
}
else _implicitKeys[i] = implicitKey;
}
}
}
public boolean isWellFormed() {
return _isWellFormed;
}
public String getLabel() {
return _label;
}
public String getKey() {
return _label.toLowerCase();
}
public int getImplicitKeyCount() {
return _implicitKeys.length;
}
public String getImplicitKey(int index) {
if (index >= _implicitKeys.length) return null;
else return _implicitKeys[index];
}
public String toString() {
return _origLabel;
}
}
}