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