blob: 0e1a9b0c070f01616b39ca51959323f4a8ccac8b [file] [log] [blame]
/**
* Copyright (c) 2002-2007 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.xsd.impl;
import java.io.IOException;
import java.io.InputStream;
import org.w3c.dom.Element;
import org.eclipse.emf.common.notify.Notification;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EAttribute;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.impl.ENotificationImpl;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.resource.ResourceSet;
import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.xsd.XSDConcreteComponent;
import org.eclipse.xsd.XSDFactory;
import org.eclipse.xsd.XSDPackage;
import org.eclipse.xsd.XSDPlugin;
import org.eclipse.xsd.XSDSchema;
import org.eclipse.xsd.XSDSchemaDirective;
import org.eclipse.xsd.util.XSDConstants;
import org.eclipse.xsd.util.XSDResourceImpl;
import org.eclipse.xsd.util.XSDSchemaLocationResolver;
import org.eclipse.xsd.util.XSDSchemaLocator;
/**
* <!-- begin-user-doc -->
* An implementation of the model object '<em><b>Schema Directive</b></em>'.
* <!-- end-user-doc -->
* <p>
* The following features are implemented:
* <ul>
* <li>{@link org.eclipse.xsd.impl.XSDSchemaDirectiveImpl#getSchemaLocation <em>Schema Location</em>}</li>
* <li>{@link org.eclipse.xsd.impl.XSDSchemaDirectiveImpl#getResolvedSchema <em>Resolved Schema</em>}</li>
* </ul>
* </p>
*
* @generated
*/
public abstract class XSDSchemaDirectiveImpl
extends XSDSchemaContentImpl
implements XSDSchemaDirective
{
/**
* The default value of the '{@link #getSchemaLocation() <em>Schema Location</em>}' attribute.
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* @see #getSchemaLocation()
* @generated
* @ordered
*/
protected static final String SCHEMA_LOCATION_EDEFAULT = null;
/**
* The cached value of the '{@link #getSchemaLocation() <em>Schema Location</em>}' attribute.
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* @see #getSchemaLocation()
* @generated
* @ordered
*/
protected String schemaLocation = SCHEMA_LOCATION_EDEFAULT;
/**
* The cached value of the '{@link #getResolvedSchema() <em>Resolved Schema</em>}' reference.
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* @see #getResolvedSchema()
* @generated
* @ordered
*/
protected XSDSchema resolvedSchema;
/**
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* @generated
*/
protected XSDSchemaDirectiveImpl()
{
super();
}
@Override
public void reset()
{
super.reset();
resolved = false;
setResolvedSchema(null);
}
/**
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* @generated
*/
@Override
protected EClass eStaticClass()
{
return XSDPackage.Literals.XSD_SCHEMA_DIRECTIVE;
}
/**
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* @generated
*/
public String getSchemaLocation()
{
return schemaLocation;
}
/**
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* @generated
*/
public void setSchemaLocation(String newSchemaLocation)
{
String oldSchemaLocation = schemaLocation;
schemaLocation = newSchemaLocation;
if (eNotificationRequired())
eNotify(new ENotificationImpl(this, Notification.SET, XSDPackage.XSD_SCHEMA_DIRECTIVE__SCHEMA_LOCATION, oldSchemaLocation, schemaLocation));
}
/**
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* @generated
*/
public XSDSchema getResolvedSchema()
{
return resolvedSchema;
}
/**
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* @generated
*/
public void setResolvedSchema(XSDSchema newResolvedSchema)
{
XSDSchema oldResolvedSchema = resolvedSchema;
resolvedSchema = newResolvedSchema;
if (eNotificationRequired())
eNotify(new ENotificationImpl(this, Notification.SET, XSDPackage.XSD_SCHEMA_DIRECTIVE__RESOLVED_SCHEMA, oldResolvedSchema, resolvedSchema));
}
/**
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* @generated
*/
@Override
public Object eGet(int featureID, boolean resolve, boolean coreType)
{
switch (featureID)
{
case XSDPackage.XSD_SCHEMA_DIRECTIVE__SCHEMA_LOCATION:
return getSchemaLocation();
case XSDPackage.XSD_SCHEMA_DIRECTIVE__RESOLVED_SCHEMA:
return getResolvedSchema();
}
return super.eGet(featureID, resolve, coreType);
}
/**
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* @generated
*/
@Override
public void eSet(int featureID, Object newValue)
{
switch (featureID)
{
case XSDPackage.XSD_SCHEMA_DIRECTIVE__SCHEMA_LOCATION:
setSchemaLocation((String)newValue);
return;
case XSDPackage.XSD_SCHEMA_DIRECTIVE__RESOLVED_SCHEMA:
setResolvedSchema((XSDSchema)newValue);
return;
}
super.eSet(featureID, newValue);
}
/**
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* @generated
*/
@Override
public void eUnset(int featureID)
{
switch (featureID)
{
case XSDPackage.XSD_SCHEMA_DIRECTIVE__SCHEMA_LOCATION:
setSchemaLocation(SCHEMA_LOCATION_EDEFAULT);
return;
case XSDPackage.XSD_SCHEMA_DIRECTIVE__RESOLVED_SCHEMA:
setResolvedSchema((XSDSchema)null);
return;
}
super.eUnset(featureID);
}
/**
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* @generated
*/
@Override
public boolean eIsSet(int featureID)
{
switch (featureID)
{
case XSDPackage.XSD_SCHEMA_DIRECTIVE__SCHEMA_LOCATION:
return SCHEMA_LOCATION_EDEFAULT == null ? schemaLocation != null : !SCHEMA_LOCATION_EDEFAULT.equals(schemaLocation);
case XSDPackage.XSD_SCHEMA_DIRECTIVE__RESOLVED_SCHEMA:
return resolvedSchema != null;
}
return super.eIsSet(featureID);
}
/**
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* @generated
*/
@Override
public String toString()
{
if (eIsProxy()) return super.toString();
StringBuffer result = new StringBuffer(super.toString());
result.append(" (schemaLocation: ");
result.append(schemaLocation);
result.append(')');
return result.toString();
}
@Override
protected void reconcileAttributes(Element changedElement)
{
super.reconcileAttributes(changedElement);
String newSchemaLocation = null;
if (changedElement.hasAttributeNS(null, XSDConstants.SCHEMALOCATION_ATTRIBUTE))
{
newSchemaLocation = changedElement.getAttributeNS(null, XSDConstants.SCHEMALOCATION_ATTRIBUTE);
}
if (newSchemaLocation == null ? getSchemaLocation() != null : !newSchemaLocation.equals(getSchemaLocation()))
{
setSchemaLocation(newSchemaLocation);
}
}
@Override
protected void changeAttribute(EAttribute eAttribute)
{
// Try to resolve again if the schema location changes and we previously failed.
//
if (resolved && getResolvedSchema() == null && eAttribute == XSDPackage.Literals.XSD_SCHEMA_DIRECTIVE__SCHEMA_LOCATION)
{
resolved = false;
}
if (!isReconciling)
{
super.changeAttribute(eAttribute);
if (eAttribute == null || eAttribute == XSDPackage.Literals.XSD_SCHEMA_DIRECTIVE__SCHEMA_LOCATION)
{
Element theElement = getElement();
if (theElement != null)
{
niceSetAttribute(theElement, XSDConstants.SCHEMALOCATION_ATTRIBUTE, getSchemaLocation());
}
}
}
if (eAttribute == XSDPackage.Literals.XSD_SCHEMA_DIRECTIVE__SCHEMA_LOCATION && getResolvedSchema() != null && getSchema().isIncrementalUpdate())
{
getSchema().reset();
}
}
@Override
protected void orphanBy(XSDSchema xsdSchema)
{
super.orphanBy(xsdSchema);
if (resolved && xsdSchema.isIncrementalUpdate())
{
xsdSchema.reset();
}
}
protected boolean resolved;
protected void resolve(String namespace, String schemaLocation)
{
if (!resolved)
{
XSDSchema xsdSchema = getSchema();
if (xsdSchema != null &&
(xsdSchema.getSchemaLocation() != null ||
((XSDSchemaImpl)xsdSchema).getPendingSchemaLocation() != null))
{
Resource resource = xsdSchema.eResource();
if (resource != null)
{
ResourceSet resourceSet = resource.getResourceSet();
if (resourceSet != null)
{
if ("".equals(namespace))
{
namespace = xsdSchema.getTargetNamespace();
}
String resolvedSchemaLocation = resolveSchemaLocation(xsdSchema, namespace, schemaLocation);
if (schemaLocation == null)
{
if (XSDConstants.isXMLNamespace(resolvedSchemaLocation))
{
resolvedSchemaLocation = XSDPlugin.INSTANCE.getBaseURL().toString() + "cache/www.w3.org/2001/xml.xsd";
}
else if (XSDConstants.SCHEMA_FOR_SCHEMA_URI_2001.equals(resolvedSchemaLocation))
{
resolvedSchemaLocation = XSDPlugin.INSTANCE.getBaseURL().toString() + "cache/www.w3.org/2001/XMLSchema.xsd";
}
}
XSDSchema resolvedSchema = locateSchema(xsdSchema, namespace, schemaLocation, resolvedSchemaLocation);
if (resolvedSchema == null)
{
URI uri = URI.createURI(resolvedSchemaLocation == null ? "" : resolvedSchemaLocation);
Resource resolvedResource = resourceSet.getResource(uri, false);
if (resolvedResource == null)
{
try
{
InputStream inputStream = resourceSet.getURIConverter().createInputStream(uri);
resolvedResource = resourceSet.createResource(URI.createURI("*.xsd"));
resolvedResource.setURI(uri);
resolvedResource.load(inputStream, resourceSet.getLoadOptions());
}
catch (IOException exception)
{
// It is generally not an error to fail to resolve.
// If a resource is actually created,
// which happens only when we can create an input stream,
// then it's an error if it's not a good schema
}
}
else if (!resolvedResource.isLoaded())
{
try
{
resolvedResource.load(resourceSet.getLoadOptions());
}
catch (IOException exception)
{
// Ignore.
}
}
if (resolvedResource != null)
{
if (resolvedResource instanceof XSDResourceImpl)
{
resolvedSchema = ((XSDResourceImpl)resolvedResource).getSchema();
}
else
{
resolvedSchema = XSDFactory.eINSTANCE.createXSDSchema();
}
}
}
resolved = true;
handleResolvedSchema(resolvedSchema);
}
}
}
}
}
protected XSDSchema locateSchema(XSDSchema xsdSchema, String namespace, String rawSchemaLocation, String resolvedSchemaLocation)
{
XSDSchemaLocator xsdSchemaLocator = (XSDSchemaLocator)EcoreUtil.getRegisteredAdapter(xsdSchema.eResource(), XSDSchemaLocator.class);
return
xsdSchemaLocator == null ?
null :
xsdSchemaLocator.locateSchema(xsdSchema, namespace, rawSchemaLocation, resolvedSchemaLocation);
}
protected String resolveSchemaLocation(XSDSchema xsdSchema, String namespace, String schemaLocation)
{
for (;;)
{
XSDSchemaLocationResolver xsdSchemaLocationResolver =
(XSDSchemaLocationResolver)EcoreUtil.getRegisteredAdapter(xsdSchema, XSDSchemaLocationResolver.class);
if (xsdSchemaLocationResolver != null)
{
return xsdSchemaLocationResolver.resolveSchemaLocation(xsdSchema, namespace, schemaLocation);
}
XSDConcreteComponent container = xsdSchema.getContainer();
if (container == null)
{
break;
}
else
{
XSDSchema containingXSDSchema = container.getSchema();
if (containingXSDSchema == null)
{
break;
}
else
{
xsdSchema = containingXSDSchema;
}
}
}
return XSDConstants.resolveSchemaLocation(xsdSchema.getSchemaLocation(), namespace, schemaLocation);
}
protected void handleResolvedSchema(XSDSchema xsdSchema)
{
// Ignore
}
}