/*******************************************************************************
* Copyright (c) 2010 SAP AG.
* 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:
* Emil Simeonov - initial API and implementation.
* Dimitar Donchev - initial API and implementation.
* Dimitar Tenev - initial API and implementation.
* Nevena Manova - initial API and implementation.
* Georgi Konstantinov - initial API and implementation.
* Stanislav Nichev - initial API and implementation.
*******************************************************************************/
package org.eclipse.wst.sse.sieditor.model.reconcile.adapters.utils;
import java.util.Collection;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.wst.wsdl.Types;
import org.eclipse.xsd.XSDConcreteComponent;
import org.eclipse.xsd.XSDImport;
import org.eclipse.xsd.XSDNamedComponent;
import org.eclipse.xsd.XSDSchema;
import org.eclipse.xsd.XSDSchemaContent;
import org.eclipse.wst.sse.sieditor.model.utils.EmfXsdUtils;
/**
* XsdSchema concrete components cache utility class. The XsdSchema has cached
* collections. These collections are not cleared on remove of referred
* namespace or import directive. This class has methods for clearing those
* cached collections.
*
*/
public class ConcreteComponentsCacheUtils {
private static final ConcreteComponentsCacheUtils INSTANCE = new ConcreteComponentsCacheUtils();
private ConcreteComponentsCacheUtils() {
}
public static ConcreteComponentsCacheUtils instance() {
return INSTANCE;
}
public void clearConcreteComponentsCacheForSchema(final XSDSchema xsdSchema, final Types eTypes) {
final Collection<String> importedNamespaces = getImportedNamespaces(xsdSchema);
clearConcreteComponentsCache(xsdSchema.getAttributeDeclarations(), xsdSchema, importedNamespaces, eTypes);
clearConcreteComponentsCache(xsdSchema.getAttributeGroupDefinitions(), xsdSchema, importedNamespaces, eTypes);
clearConcreteComponentsCache(xsdSchema.getModelGroupDefinitions(), xsdSchema, importedNamespaces, eTypes);
clearConcreteComponentsCache(xsdSchema.getTypeDefinitions(), xsdSchema, importedNamespaces, eTypes);
clearConcreteComponentsCache(xsdSchema.getIdentityConstraintDefinitions(), xsdSchema, importedNamespaces, eTypes);
clearConcreteComponentsCache(xsdSchema.getNotationDeclarations(), xsdSchema, importedNamespaces, eTypes);
clearConcreteComponentsCache(xsdSchema.getElementDeclarations(), xsdSchema, importedNamespaces, eTypes);
}
private <T extends XSDConcreteComponent> void clearConcreteComponentsCache(final EList<T> concreteComponents,
final XSDSchema xsdSchema, final Collection<String> importedNamespaces, final Types eTypes) {
clearCachedComponentsFromMissingSchema(concreteComponents, eTypes);
clearCachedComponentsFromMissingImport(concreteComponents, importedNamespaces);
}
private <T extends XSDConcreteComponent> void clearCachedComponentsFromMissingSchema(final EList<T> concreteComponents,
final Types eTypes) {
if (eTypes == null) {
return;
}
final List<XSDConcreteComponent> toRemove = new LinkedList<XSDConcreteComponent>();
for (final XSDConcreteComponent concreteComponent : concreteComponents) {
final EObject eContainer = concreteComponent.eContainer();
final String enclosingDefintionLocation = eTypes.getEnclosingDefinition().getLocation();
if (eContainer instanceof XSDSchema && ((XSDSchema) eContainer).getSchemaLocation() != null
&& ((XSDSchema) eContainer).getSchemaLocation().equals(enclosingDefintionLocation)
&& !eTypes.getSchemas().contains(eContainer)) {
toRemove.add(concreteComponent);
}
}
concreteComponents.removeAll(toRemove);
}
private <T extends XSDConcreteComponent> void clearCachedComponentsFromMissingImport(final EList<T> concreteComponents,
final Collection<String> importedNamespaces) {
final List<XSDConcreteComponent> toRemove = new LinkedList<XSDConcreteComponent>();
for (final XSDConcreteComponent concreteComponent : concreteComponents) {
final XSDSchema concreteComponentSchema = ((XSDNamedComponent) concreteComponent).getSchema();
final String componentTargetNamespace = concreteComponentSchema == null ? null : concreteComponentSchema
.getTargetNamespace();
if (!importedNamespaces.contains(componentTargetNamespace)
&& !EmfXsdUtils.isSchemaForSchemaNS(componentTargetNamespace)) {
toRemove.add(concreteComponent);
}
}
concreteComponents.removeAll(toRemove);
}
private Collection<String> getImportedNamespaces(final XSDSchema xsdSchema) {
final Set<String> importedNamespaces = new HashSet<String>();
for (final XSDSchemaContent schemaContent : xsdSchema.getContents()) {
if (!(schemaContent instanceof XSDImport)) {
continue;
}
importedNamespaces.add(((XSDImport) schemaContent).getNamespace());
}
return importedNamespaces;
}
}