/**
* Copyright 2004-2016 Riccardo Solmi. All rights reserved.
* This file is part of the Whole Platform.
*
* The Whole Platform is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* The Whole Platform is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with the Whole Platform. If not, see <http://www.gnu.org/licenses/>.
*/
package org.whole.lang.xsd.resources;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import org.whole.lang.bindings.BindingManagerFactory;
import org.whole.lang.bindings.IBindingManager;
import org.whole.lang.model.IEntity;
import org.whole.lang.operations.InterpreterOperation;
import org.whole.lang.reflect.AbstractLanguageDeployer;
import org.whole.lang.reflect.ReflectionFactory;
import org.whole.lang.resources.IResource;
import org.whole.lang.resources.ResourceRegistry;
import org.whole.lang.resources.URLURIResolver;
import org.whole.lang.xml.util.InputStreamInput;
import org.whole.lang.xsd.codebase.MappingStrategyRegistry;
import org.whole.lang.xsd.codebase.SchemaMapping;
import org.whole.lang.xsd.model.Schema;
import org.whole.lang.xsd.util.NamespaceUtils;
import org.whole.lang.xsd.util.SchemaUtils;
/**
* @author Enrico Persiani, Riccardo Solmi
*/
public class XsdRegistry extends ResourceRegistry<IResource> {
private static class SingletonHolder {
private static final XsdRegistry instance = new XsdRegistry();
}
public static final XsdRegistry instance() {
XsdRegistry registry = SingletonHolder.instance;
String registryId = Schema.class.getName();
if (!ResourceRegistry.hasRegistry(registryId)) {
ResourceRegistry.putRegistry(registryId, registry);
// setup some internal schemas and mappings
registry.deploySchemaForSchema();
registry.predeploySchemas("XMLNamespace.xsd");
}
return registry;
}
public static void initialize() {
instance();
}
public static void deinitialize() {
XsdRegistry registry = SingletonHolder.instance;
registry.removeSchema(NamespaceUtils.XML_NAMESPACE_URI);
registry.removeSchema(NamespaceUtils.XSD_NAMESPACE_URI);
}
protected XsdRegistry() {
super(new URLURIResolver());
getResourceFactoryRegistry().setDefaultResourceFactory(
new XsdResourceFactory(getResourceFactoryRegistry()));
}
protected void deploySchemaForSchema() {
String location = "XMLSchema.xsd";
MappingStrategyRegistry.instance().putMappingModel(new SchemaMapping().create());
//FIXME replace with real schema for schema model with annotations
InputStream is = getClass().getResourceAsStream(location);
Schema schemaForSchema = SchemaUtils.load(new InputStreamInput(is));
putSchema(location, schemaForSchema, true);
}
protected void predeploySchemas(String... locations) {
IBindingManager args = BindingManagerFactory.instance.createArguments();
args.wDefValue("predeployed", true);
args.wDefValue("fileName", "");
args.wDefValue("fileExtension", "");
args.wDefValue("fileNameWithExtension", "");
args.wDefValue("fileLocationURI", "");
for (String location : locations) {
String fileNameWithExtension = location.replaceFirst("^.*/", "");
String filename = fileNameWithExtension.replaceFirst("\\.[^\\.]*$", "");
args.wSetValue("fileName", filename);
args.wSetValue("fileExtension", fileNameWithExtension.substring(filename.length()+1));
args.wSetValue("fileNameWithExtension", fileNameWithExtension);
args.wSetValue("fileLocationURI", getClass().getResource(location).toExternalForm());
InputStream is = getClass().getResourceAsStream(location);
Schema schema = SchemaUtils.load(new InputStreamInput(is));
InterpreterOperation.interpret(schema, args);
}
}
public boolean putSchema(String location, Schema schema) {
return putSchema(location, schema, false);
}
public boolean putSchema(String location, Schema schema, boolean predeployed) {
String targetNamespace = schema.getTargetNamespace().getValue();
// updateSchemaLocation(targetNamespace, location);
//FIXME put location somewhere
return addResource(schema, targetNamespace, false);
// return schemaMap.put(targetNamespace, schema) != null;
}
public boolean removeSchema(Schema schema) {
return removeSchema(schema.getTargetNamespace().getValue());
}
public boolean removeSchema(String targetNamespace) {
// updateSchemaLocation(targetNamespace, null);
//FIXME clear location somewhere
boolean removed = removeResource(targetNamespace);
if (removed)
ReflectionFactory.undeploy(new AbstractLanguageDeployer() {
public void deploy(ReflectionFactory platform) {
}
public void undeploy(ReflectionFactory platform) {
platform.removeLanguageKit(targetNamespace);
}
});
return removed;
// return schemaMap.remove(targetNamespace) != null;
}
public Collection<Schema> schemas() {
Collection<IResource> resources = getResources(true, new Comparator<IResource>() {
public int compare(IResource s1, IResource s2) {
return s1.getNamespace().compareTo(s2.getNamespace());
}
});
List<Schema> schemas = new ArrayList<Schema>(resources.size());
for (IResource resource : resources)
schemas.add(resource.<Schema>getEntity());
return Collections.unmodifiableList(schemas);
}
public Schema getSchemaFor(IEntity entity) {
return getSchemaFor(entity.wGetLanguageKit().getURI());
}
public Schema getSchemaFor(String targetNamespace) {
IResource resource = getResource(targetNamespace, false, null);
return resource != null ? resource.<Schema>getEntity() : null;
}
public boolean containsSchema(Schema s) {
return containsSchemaFor(s.getTargetNamespace().getValue());
}
public boolean containsSchemaFor(IEntity entity) {
return containsSchemaFor(entity.wGetLanguageKit().getURI());
}
public boolean containsSchemaFor(String targetNamespace) {
return containsResource(targetNamespace, false, null);
}
}