/**
* Copyright (c) 2004-2009 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.util;
//import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.eclipse.emf.common.util.BasicDiagnostic;
import org.eclipse.emf.common.util.Diagnostic;
import org.eclipse.emf.common.util.DiagnosticChain;
import org.eclipse.emf.ecore.EValidator;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EDataType;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.emf.ecore.plugin.EcorePlugin;
/**
* A validity checker for basic EObject constraints.
*/
public class Diagnostician implements EValidator.SubstitutionLabelProvider, EValidator
{
public static final Diagnostician INSTANCE = new Diagnostician();
protected EValidator.Registry eValidatorRegistry;
public Diagnostician(EValidator.Registry eValidatorRegistry)
{
this.eValidatorRegistry = eValidatorRegistry;
}
public Diagnostician()
{
this(EValidator.Registry.INSTANCE);
}
public String getObjectLabel(EObject eObject)
{
return EcoreUtil.getIdentification(eObject);
}
public String getFeatureLabel(EStructuralFeature eStructuralFeature)
{
return eStructuralFeature.getName();
}
public String getValueLabel(EDataType eDataType, Object value)
{
return EcoreUtil.convertToString(eDataType, value);
}
/**
* @since 2.4
*/
public Map<Object, Object> createDefaultContext()
{
Map<Object, Object> context = new HashMap<Object, Object>();
context.put(EValidator.SubstitutionLabelProvider.class, this);
context.put(EValidator.class, this);
return context;
}
/**
* @since 2.4
*/
public BasicDiagnostic createDefaultDiagnostic(EObject eObject)
{
return
new BasicDiagnostic
(EObjectValidator.DIAGNOSTIC_SOURCE,
0,
EcorePlugin.INSTANCE.getString("_UI_DiagnosticRoot_diagnostic", new Object[] { getObjectLabel(eObject) }),
new Object [] { eObject });
}
/**
* @since 2.4
*/
public BasicDiagnostic createDefaultDiagnostic(EDataType eDataType, Object value)
{
return
new BasicDiagnostic
(EObjectValidator.DIAGNOSTIC_SOURCE,
0,
EcorePlugin.INSTANCE.getString("_UI_DiagnosticRoot_diagnostic", new Object [] { getValueLabel(eDataType, value) }),
new Object [] { value, eDataType });
}
public Diagnostic validate(EObject eObject)
{
BasicDiagnostic diagnostics = createDefaultDiagnostic(eObject);
validate(eObject, diagnostics, createDefaultContext());
return diagnostics;
}
/**
* @since 2.4
*/
public Diagnostic validate(EObject eObject, Map<?, ?> contextEntries)
{
BasicDiagnostic diagnostics = createDefaultDiagnostic(eObject);
Map<Object, Object> context = createDefaultContext();
context.putAll(contextEntries);
validate(eObject, diagnostics, context);
return diagnostics;
}
/**
* Validates the object in the given context, optionally producing diagnostics.
* @param eObject the object to validate.
* @param diagnostics a place to accumulate diagnostics; if it's <code>null</code>, no diagnostics should be produced.
* @return whether the object is valid.
*/
public boolean validate(EObject eObject, DiagnosticChain diagnostics)
{
return validate(eObject, diagnostics, createDefaultContext());
}
public boolean validate(EObject eObject, DiagnosticChain diagnostics, Map<Object, Object> context)
{
return validate(eObject.eClass(), eObject, diagnostics, context);
}
public boolean validate(EClass eClass, EObject eObject, DiagnosticChain diagnostics, Map<Object, Object> context)
{
Object eValidator;
EClass eType = eClass;
while ((eValidator = eValidatorRegistry.get(eType.eContainer())) == null)
{
List<EClass> eSuperTypes = eType.getESuperTypes();
if (eSuperTypes.isEmpty())
{
eValidator = eValidatorRegistry.get(null);
break;
}
else
{
eType = eSuperTypes.get(0);
}
}
boolean circular = context.get(EObjectValidator.ROOT_OBJECT) == eObject;
@SuppressWarnings("null")
boolean result = ((EValidator)eValidator).validate(eClass, eObject, diagnostics, context);
if ((result || diagnostics != null) && !circular)
{
result &= doValidateContents(eObject, diagnostics, context);
}
return result;
}
protected boolean doValidateContents(EObject eObject, DiagnosticChain diagnostics, Map<Object, Object> context)
{
List<EObject> eContents = eObject.eContents();
if (!eContents.isEmpty())
{
Iterator<EObject> i = eContents.iterator();
EObject child = i.next();
boolean result = validate(child, diagnostics, context);
while (i.hasNext() && (result || diagnostics != null))
{
child = i.next();
result &= validate(child, diagnostics, context);
}
return result;
}
else
{
return true;
}
}
public Diagnostic validate(EDataType eDataType, Object value)
{
BasicDiagnostic diagnostics = createDefaultDiagnostic(eDataType, value);
validate(eDataType, value, diagnostics, createDefaultContext());
return diagnostics;
}
public boolean validate(EDataType eDataType, Object value, DiagnosticChain diagnostics, Map<Object, Object> context)
{
Object eValidator = eValidatorRegistry.get(eDataType.eContainer());
if (eValidator == null)
{
eValidator = eValidatorRegistry.get(null);
}
return ((EValidator)eValidator).validate(eDataType, value, diagnostics, context);
}
}