/**
* Copyright (c) 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 v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM - Initial API and implementation
*/
package org.eclipse.emf.ecore.xmi.impl;
import java.util.LinkedHashMap;
import java.util.Map;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.xmi.XMLResource;
/**
* This resource entity handler implementation extends the URI handler implementation
* so that this object can be used as both a resource entity handler and a URI handler
* since it's far more efficient to deresolve a URI once to compute the entity value
* than to deresolve it for each use and then map that deresolved result to an entity.
* For this reason, this implementation overrides {@link #deresolve} to return the incoming URI.
*/
public class ResourceEntityHandlerImpl extends URIHandlerImpl implements XMLResource.ResourceEntityHandler
{
protected String entityName;
protected int count = 1;
protected Map<String, String> nameToValueMap = new LinkedHashMap<String, String>();
protected Map<String, String> valueToNameMap = new LinkedHashMap<String, String>();
/**
* Creates an instance that will generate entity names based on the given entity name
* followed by the {@link #count} starting from 1 to ensure uniqueness.
* @param entityName
*/
public ResourceEntityHandlerImpl(String entityName)
{
this.entityName = entityName;
}
/**
* Returns the given URI.
* @param uri the URI to deresolve.
*/
@Override
public URI deresolve(URI uri)
{
return uri;
}
/**
* Returns the deresolved URI by calling super.
* @param uri the URI to deresolve.
*/
protected URI doDeresolve(URI uri)
{
return super.deresolve(uri);
}
/**
* Sets the base URI and if the URI has changed,
* resolves all the entity URIs values against the old base URI
* and then deresolves them against the new baseURI.
* @param uri the new base URI.
*/
@Override
public void setBaseURI(URI uri)
{
boolean unchanged = uri == null ? baseURI == null : uri.equals(baseURI);
if (!unchanged)
{
for (Map.Entry<String, String> entry : nameToValueMap.entrySet())
{
entry.setValue(resolve(URI.createURI(entry.getValue())).toString());
}
}
doSetBaseURI(uri);
if (!unchanged)
{
valueToNameMap.clear();
for (Map.Entry<String, String> entry : nameToValueMap.entrySet())
{
valueToNameMap.put(entry.getValue(), entry.getKey());
entry.setValue(doDeresolve(URI.createURI(entry.getValue())).toString());
}
}
}
/**
* Sets the base URI by calling super.
* @param uri
*/
protected void doSetBaseURI(URI uri)
{
super.setBaseURI(uri);
}
/**
* Resets the handler to its initial state.
*/
public void reset()
{
valueToNameMap.clear();
nameToValueMap.clear();
count = 1;
}
public String getEntityName(String entityValue)
{
String result = valueToNameMap.get(entityValue);
if (result == null)
{
result = generateEntityName(entityValue);
if (result != null)
{
valueToNameMap.put(entityValue, result);
nameToValueMap.put(result, entityValue);
}
}
return result;
}
/**
* Generates a new unique entity name for the given entity value.
* @param entityValue the value for which an entity name is needed.
* @return a new unique entity name.
*/
protected String generateEntityName(String entityValue)
{
for (String result = entityName + count;; result = entityName + ++count)
{
if (!nameToValueMap.containsKey(result))
{
return result;
}
}
}
public void handleEntity(String entityName, String entityValue)
{
nameToValueMap.put(entityName, entityValue);
valueToNameMap.put(entityValue, entityName);
}
public Map<String, String> getNameToValueMap()
{
// Deresolve all the URI against the current base URI.
//
Map<String, String> result = new LinkedHashMap<String, String>();
for (Map.Entry<String, String> entry : nameToValueMap.entrySet())
{
result.put(entry.getKey(), doDeresolve(URI.createURI(entry.getValue())).toString());
}
return result;
}
}