/** | |
* Copyright (c) 2013, 2016 Angelo ZERR. | |
* 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: | |
* Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation | |
*/ | |
package org.eclipse.wst.json.core.internal.schema; | |
import java.io.IOException; | |
import java.net.MalformedURLException; | |
import java.net.URL; | |
import org.eclipse.core.runtime.CoreException; | |
import org.eclipse.core.runtime.IConfigurationElement; | |
import org.eclipse.core.runtime.IExtensionPoint; | |
import org.eclipse.core.runtime.IExtensionRegistry; | |
import org.eclipse.core.runtime.Platform; | |
import org.eclipse.json.schema.IJSONSchemaDocument; | |
import org.eclipse.json.schema.IJSONSchemaProcessor; | |
import org.eclipse.wst.common.uriresolver.internal.provisional.URIResolverPlugin; | |
import org.eclipse.wst.common.uriresolver.internal.util.URIHelper; | |
import org.eclipse.wst.json.core.JSONCorePlugin; | |
import org.eclipse.wst.json.core.document.IJSONDocument; | |
import org.eclipse.wst.json.core.document.IJSONModel; | |
import org.eclipse.wst.json.core.document.IJSONNode; | |
import org.eclipse.wst.json.core.document.IJSONPair; | |
import org.eclipse.wst.json.core.document.IJSONValue; | |
import org.eclipse.wst.json.core.internal.Logger; | |
import org.eclipse.wst.json.core.util.JSONUtil; | |
public class SchemaProcessorRegistryReader { | |
protected static final String EXTENSION_POINT_ID = "schemaProcessors"; //$NON-NLS-1$ | |
protected static final String TAG_CONTRIBUTION = "schemaProcessor"; //$NON-NLS-1$ | |
public static SchemaProcessorRegistryReader INSTANCE = null; | |
private IJSONSchemaProcessor defaultProcessor; | |
public static SchemaProcessorRegistryReader getInstance() { | |
if (INSTANCE == null) { | |
INSTANCE = new SchemaProcessorRegistryReader(); | |
INSTANCE.readRegistry(); | |
} | |
return INSTANCE; | |
} | |
public IJSONSchemaProcessor getDefaultProcessor() { | |
return defaultProcessor; | |
} | |
public IJSONSchemaDocument getSchemaDocument(IJSONNode node) | |
throws IOException { | |
return getSchemaDocument(node.getModel()); | |
} | |
public IJSONSchemaDocument getSchemaDocument(IJSONModel model) | |
throws IOException { | |
IJSONSchemaProcessor processor = getDefaultProcessor(); | |
if (processor == null) { | |
return null; | |
} | |
IJSONDocument document = model.getDocument(); | |
IJSONNode jsonObject = document.getFirstChild(); | |
if (jsonObject != null) { | |
IJSONNode child = jsonObject.getFirstChild(); | |
while (child != null) { | |
if (child instanceof IJSONPair) { | |
IJSONPair pair = (IJSONPair) child; | |
String name = pair.getName(); | |
IJSONValue valueNode = pair.getValue(); | |
if (valueNode != null && "$schema".equals(name)) { //$NON-NLS-1$ | |
String schema = JSONUtil.getString(valueNode); | |
try { | |
if (schema != null) { | |
schema = URIHelper.addImpliedFileProtocol(schema); | |
new URL(schema); | |
return processor.getSchema(schema); | |
} | |
} catch (MalformedURLException e) { | |
} | |
} | |
} | |
child = child.getNextSibling(); | |
} | |
} | |
String base = model == null || model.getResolver() == null ? | |
null : model.getResolver().getFileBaseLocation(); | |
/** | |
* We shouldn't assert a failure because the catalog does not require a | |
* base location to operate and it will be called from non-file-based | |
* scenarios. | |
* | |
* https://bugs.eclipse.org/bugs/show_bug.cgi?id=206176 | |
*/ | |
// Assert.isNotNull(base, "Base location is expected to be non null."); //$NON-NLS-1$ | |
if (base != null) { | |
base = URIHelper.addImpliedFileProtocol(base); | |
} | |
String schemaURL = resolve(base, null, null); | |
if (schemaURL != null) { | |
return processor.getSchema(schemaURL); | |
} | |
return null; | |
} | |
private String getFileMatch(String location) { | |
if (location == null) { | |
return null; | |
} | |
int index = location.lastIndexOf('/'); | |
if (index == -1) { | |
index = location.lastIndexOf('\\'); | |
} | |
if (index != -1) { | |
return location.substring(index, location.length()); | |
} | |
return location; | |
} | |
private String resolve(String base, String publicId, String systemId) { | |
String result = systemId; | |
result = URIResolverPlugin.createResolver().resolve(base, publicId, | |
systemId); | |
return result; | |
} | |
/** | |
* read from plugin registry and parse it. | |
*/ | |
protected void readRegistry() { | |
IExtensionRegistry pluginRegistry = Platform.getExtensionRegistry(); | |
IExtensionPoint point = pluginRegistry | |
.getExtensionPoint(JSONCorePlugin.getDefault().getBundle() | |
.getSymbolicName(), EXTENSION_POINT_ID); | |
if (point != null) { | |
IConfigurationElement[] elements = point.getConfigurationElements(); | |
for (int i = 0; i < elements.length; i++) { | |
readElement(elements[i]); | |
} | |
} | |
} | |
protected void readElement(IConfigurationElement element) { | |
if (TAG_CONTRIBUTION.equals(element.getName())) { | |
String id = element.getAttribute("id"); | |
String name = element.getAttribute("name"); | |
try { | |
IJSONSchemaProcessor schemaProcessor = (IJSONSchemaProcessor) element | |
.createExecutableExtension("class"); | |
this.defaultProcessor = schemaProcessor; | |
} catch (CoreException e) { | |
Logger.logException(e); | |
} | |
} | |
} | |
} |