org.eclipse.persistence.sdo.helper.SchemaResolverWrapper Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of eclipselink Show documentation
Show all versions of eclipselink Show documentation
EclipseLink build based upon Git transaction f2b9fc5
/*
* Copyright (c) 1998, 2020 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0,
* or the Eclipse Distribution License v. 1.0 which is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
*/
// Contributors:
// Oracle - initial API and implementation from Oracle TopLink
package org.eclipse.persistence.sdo.helper;
import java.util.ArrayList;
import java.util.List;
import javax.xml.transform.Source;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.sax.SAXSource;
import javax.xml.transform.stream.StreamSource;
import org.eclipse.persistence.exceptions.SDOException;
import org.xml.sax.InputSource;
/**
* Purpose: Allow the contained schema resolver to resolve a schema based on a given namespace and schema location, and
* return either the resolved schema source or null, depending on whether the schema had been processed previously.
*
Responsibilities:
* - Allow the contained schema resolver to return the referenced Schema given the source schema and namespace and
* schemaLocation values from an import or include
*
- Keep track of previously processed schemas to avoid multiple processing and infinite looping
*
*
* @see org.eclipse.persistence.sdo.helper.SchemaResolver
* @see org.eclipse.persistence.sdo.helper.DefaultSchemaResolver
*/
public class SchemaResolverWrapper {
private SchemaResolver schemaResolver;
private List systemIdList;
/**
* This constructor sets schemaResolver to the given value.
*
* @param resolver the SchemaResolver implementation that will be used to resolve
* imports/includes from a give source schema.
*/
public SchemaResolverWrapper(SchemaResolver resolver) {
schemaResolver = resolver;
systemIdList = new ArrayList();
}
/**
* Resolve the Source if only a system ID is specified.
*/
public Source resolveSchema(Source sourceXSD) {
Source resolvedSchemaSource = null;
if(sourceXSD instanceof StreamSource) {
StreamSource streamSource = (StreamSource) sourceXSD;
if(null == streamSource.getInputStream() && null == streamSource.getReader()) {
resolvedSchemaSource = resolveSchema(streamSource.getPublicId(), streamSource.getSystemId());
}
} else if(sourceXSD instanceof SAXSource) {
SAXSource saxSource = (SAXSource) sourceXSD;
InputSource inputSource = saxSource.getInputSource();
if(null == inputSource) {
resolvedSchemaSource = resolveSchema(saxSource.getSystemId());
} else if(null == inputSource.getByteStream() && null == inputSource.getCharacterStream()){
resolvedSchemaSource = resolveSchema(inputSource.getPublicId(), inputSource.getSystemId());
}
} else if(sourceXSD instanceof DOMSource) {
DOMSource domSource = (DOMSource) sourceXSD;
if(null == domSource.getNode()) {
resolvedSchemaSource = resolveSchema(domSource.getSystemId());
}
} else if(null != sourceXSD.getSystemId()) {
resolvedSchemaSource = resolveSchema(sourceXSD.getSystemId());
}
if(resolvedSchemaSource != null) {
return resolvedSchemaSource;
}
return sourceXSD;
}
/**
* Allow the SchemaResolver implementation to attempt to return the referenced Schema based on
* given source schema, namespace and schemaLocation values from an import or include. If the
* resolver fails, this method will attempt to resolve the schema
*
* @param sourceXSD The Source object of the source schema
* @param namespace The namespace portion of the import/include
* @param schemaLocation The schemaLocation portion of the import/include
* @return Source for the referenced Schema or null if processing the referenced
* schema should be skipped
*/
public Source resolveSchema(Source sourceXSD, String namespace, String schemaLocation) {
// Add sourceXSD's SystemId to the processed schema list to avoid re-processing
addSchemaToList(sourceXSD.getSystemId());
Source schemaSource = schemaResolver.resolveSchema(sourceXSD, namespace, schemaLocation);
if (schemaSource != null) {
String sysId = schemaSource.getSystemId();
if (shouldProcessSchema(sysId)) {
return schemaSource;
}
}
return null;
}
public Source resolveSchema(String systemId) {
return resolveSchema(null, systemId);
}
public Source resolveSchema(String publicId, String systemId) {
if(!addSchemaToList(systemId)) {
return null;
}
try {
InputSource inputSource = schemaResolver.resolveEntity(publicId, systemId);
if(inputSource != null) {
return new SAXSource(inputSource);
}
} catch(Exception ex) {
throw SDOException.errorResolvingSchema(ex);
}
return null;
}
/**
* Indicates if the schema represented by the given systemId (schema URL string) should be processed.
* If systemId exists in the list, it should not be processed; otherwise, it will be added to the
* list and true returned to indicate processing is required.
*
* @param systemId a String that conforms to the URI syntax
* @return true if systemId is null or does not exist in the list of previously processed schemas,
* false otherwise
*/
private boolean shouldProcessSchema(String systemId) {
if (systemId == null) {
return true;
}
return addSchemaToList(systemId);
}
/**
* Add the given SystemId to the list of processed schemas, if it isn't already in the list.
*
* @param systemId a String that conforms to the URI syntax
* @return true if systemId was added to the list (hence the associated schema should be processed),
* false if the id was not added to the list or systemId is null.
*/
private boolean addSchemaToList(String systemId) {
if (systemId == null || systemIdList.contains(systemId)) {
return false;
}
systemIdList.add(systemId);
return true;
}
/**
* Return the SchemaResolver for this wrapper instance.
*
* @return
*/
public SchemaResolver getSchemaResolver() {
return schemaResolver;
}
}