/*
* JBoss, Home of Professional Open Source.
*
* See the LEGAL.txt file distributed with this work for information regarding copyright ownership and licensing.
*
* See the AUTHORS.txt file distributed with this work for a full listing of individual contributors.
*/
package org.teiid.designer.modelgenerator.xml.wizards;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.resource.ResourceSet;
import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl;
import org.eclipse.xsd.XSDSchema;
import org.eclipse.xsd.util.XSDResourceFactoryImpl;
import org.eclipse.xsd.util.XSDResourceImpl;
import org.teiid.designer.core.validation.rules.CoreValidationRulesUtil;
import org.teiid.designer.modelgenerator.xml.XmlImporterUiPlugin;
import org.teiid.designer.modelgenerator.xml.model.UserSettings;
import org.teiid.designer.schema.tools.model.schema.QName;
import org.teiid.designer.schema.tools.model.schema.RootElement;
import org.teiid.designer.schema.tools.model.schema.SchemaModel;
import org.teiid.designer.schema.tools.model.schema.SchemaObject;
import org.teiid.designer.schema.tools.processing.RelationshipProcessor;
import org.teiid.designer.schema.tools.processing.RelationshipProcessorFactory;
import org.teiid.designer.schema.tools.processing.SchemaProcessor;
import org.teiid.designer.schema.tools.processing.SchemaUtil;
import org.teiid.designer.schema.tools.processing.internal.SchemaProcessorImpl;
/**
* @since 8.0
*/
public class StateManager {
/** Key=File or IFile, Value=Resource. */
protected Map xsds = new HashMap();
private ResourceSet resourceSet;
// The model of the accumulated schemas
private SchemaModel schemaModel;
// The schemaModel for rollup (modification)
private SchemaModel processedModel;
// The list of root elements that the user has selected.
private Collection selectedRoots;
// Processing objects
private SchemaProcessor processor;
private RelationshipProcessor relationshipProcessor;
// Internal data indicating the state of the state.
private boolean schemasModified = false;
private boolean modelDirty = true;
// Other State
UserSettings userSettings;
int catalogType = XsdAsRelationalImportWizard.NO_CATALOG_VAL;
private String customCatalogName;
public static final int SOURCE_DOCUMENT = 0;
public static final int SOURCE_HTTP_NO_PARAMS = 1;
public static final int SOURCE_HTTP_PARAMS = 2;
public static final int SOURCE_HTTP_REQUEST_DOC = 3;
public static final int SOURCE_ACS = 4;
private boolean acsMode = false;
public StateManager( UserSettings userSettings ) {
this.userSettings = userSettings;
Resource.Factory.Registry.INSTANCE.getExtensionToFactoryMap().put("wsdl", new XSDResourceFactoryImpl()); //$NON-NLS-1$
Resource.Factory.Registry.INSTANCE.getExtensionToFactoryMap().put("xsd", new XSDResourceFactoryImpl()); //$NON-NLS-1$
resourceSet = new ResourceSetImpl();
}
public void addSchema( Object key,
URI uri ) {
xsds.put(key, uri);
schemasModified = true;
}
public Set getSchemaKeySet() {
return xsds.keySet();
}
public int getSchemaCount() {
return xsds.size();
}
public Object removeSchema( Object key ) {
return xsds.remove(key);
}
public List getSchemaURIs() {
return new ArrayList(xsds.values());
}
public Collection getPotentialRoots() throws Exception {
if (null == processor) {
processor = new SchemaProcessorImpl(UserSettings.getMergedChildSep());
}
if (null == schemaModel || schemasModified) {
initSchemaModel();
schemasModified = false;
}
if (null == selectedRoots) {
selectedRoots = new HashSet();
}
List potentialRoots = schemaModel.getPotentialRootElements();
for (Iterator iter = potentialRoots.iterator(); iter.hasNext();) {
RootElement elem = (RootElement)iter.next();
if (elem.isUseAsRoot()) {
selectedRoots.add(elem);
}
}
return potentialRoots;
}
public void setSelectedRoots( Collection selectedRoots ) {
this.selectedRoots = selectedRoots;
modelDirty = true;
}
public boolean isUserSelectedRoot( SchemaObject element ) {
for (Iterator iter = selectedRoots.iterator(); iter.hasNext();) {
RootElement root = (RootElement)iter.next();
if (root.getKey() == element.getKey()) {
return true;
}
}
return false;
}
private void initSchemaModel() throws Exception {
List schemaUriList = Arrays.asList(xsds.values().toArray());
List schemas = new ArrayList(schemaUriList.size());
Iterator iter = schemaUriList.iterator();
while (iter.hasNext()) {
URI uri = (URI)iter.next();
URI resourceUri;
Resource res;
File file = new File(uri.toString());
if ((uri.scheme() != null && uri.scheme().equals("ACSResponse")) || //$NON-NLS-1$
(uri.scheme() != null && uri.scheme().equals("ACSRequest"))) { //$NON-NLS-1$
InputStream stream = new ByteArrayInputStream(uri.fragment().getBytes("UTF-8")); //$NON-NLS-1$
XSDResourceImpl acsResource = new XSDResourceImpl();
acsResource.setURI(uri); // get around a defect in XSDResourceImpl.
resourceSet.getResources().add(acsResource);
acsResource.load(stream, new HashMap());
res = acsResource;
} else {
if (file.isFile()) {
resourceUri = URI.createFileURI(file.getCanonicalPath().toString());
} else {
resourceUri = uri;
}
res = resourceSet.getResource(resourceUri, true);
}
schemas.add(((XSDResourceImpl)res).getSchema());
}
XSDSchema[] result = new XSDSchema[schemas.size()];
schemas.toArray(result);
processor.processSchemas(result);
schemaModel = processor.getSchemaModel();
}
public SchemaModel getProcessedModel() {
if (null == processedModel || !modelDirty) {
if (null == relationshipProcessor) {
relationshipProcessor = RelationshipProcessorFactory.getQueryOptimizingProcessor(userSettings.get_C_threshold(),
userSettings.get_P_threshold(),
userSettings.get_F_threshold());
}
processedModel = schemaModel.copy();
HashSet roots = new HashSet(selectedRoots);
processedModel.setSelectedRootElements(roots);
relationshipProcessor.calculateRelationshipTypes(processedModel);
}
modelDirty = false;
return processedModel;
}
public SchemaModel getSchemaModel() {
return schemaModel;
}
public RelationshipProcessor getRelationshipProcessor() {
return relationshipProcessor;
}
public List getCatalogs() {
List retVal = null;
switch (getCatalogType()) {
case XsdAsRelationalImportWizard.NAMESPACE_CATALOG_VAL:
case XsdAsRelationalImportWizard.NO_CATALOG_VAL:
retVal = new ArrayList(0);
break;
case XsdAsRelationalImportWizard.FILENAME_CATALOG_VAL:
retVal = getFileNames();
break;
case XsdAsRelationalImportWizard.CUSTOM_CATALOG_VAL:
retVal = new ArrayList(1);
retVal.add(customCatalogName);
break;
default:
retVal = new ArrayList();
break;
}
return retVal;
}
public int getCatalogType() {
return catalogType;
}
public void setCatalogType( int catalogType ) {
this.catalogType = catalogType;
}
private List getFileNames() {
ArrayList retVal = new ArrayList(xsds.size());
Collection xsdValues = xsds.values();
for (Iterator i = xsdValues.iterator(); i.hasNext();) {
URI uri = (URI)i.next();
retVal.add(SchemaUtil.shortenFileName(SchemaProcessorImpl.getSchemaFromURI(uri).getSchemaLocation()));
}
return retVal;
}
public void setCustomCatalogName( String name ) {
customCatalogName = name;
}
public String getCustomCatalogName() {
return customCatalogName;
}
public boolean isUsingNoCatalog() {
return catalogType == XsdAsRelationalImportWizard.NO_CATALOG_VAL;
}
public boolean isUsingNamespaces() {
return catalogType == XsdAsRelationalImportWizard.NAMESPACE_CATALOG_VAL;
}
public boolean isUsingFileNames() {
return catalogType == XsdAsRelationalImportWizard.FILENAME_CATALOG_VAL;
}
public boolean isUsingCustom() {
return catalogType == XsdAsRelationalImportWizard.CUSTOM_CATALOG_VAL;
}
public Map getNamespaces() {
return schemaModel.getNamespaces();
}
public String getFirstCatalog() {
String catalog = ""; //$NON-NLS-1$
for (Iterator resourceIter = xsds.values().iterator(); resourceIter.hasNext();) {
Object o = resourceIter.next();
URI uri = (URI)o;
catalog = SchemaProcessorImpl.getSchemaFromURI(uri).getTargetNamespace();
}
return catalog;
}
// Returns the qname of the request table (whether or not request-response
// is enabled). More accurately, it returns the qname of what the request table
// would be if thee is one.
public QName getRequestResponseTable() {
List catalogs = getCatalogs();
int global = -1;
int countExcludingGlobal = catalogs.size();
for (int i = 0; i < catalogs.size(); i++) {
if (catalogs.get(i) == null || catalogs.get(i).equals(StateManager.globalNamespace)) {
global = i;
--countExcludingGlobal;
break;
}
}
String namespace;
switch (countExcludingGlobal) {
case 0:
// only namespace is global: use it
namespace = StateManager.globalNamespace;
break;
case 1:
// only one namespace other than global: use the namespace that is not global
if (global == 0) {
namespace = (String)catalogs.get(1);
} else {
namespace = (String)catalogs.get(0);
}
break;
default:
// more than one namespace other than global: since we don't know which
// to use, use global it it exists, otherwise use the first namespace
// alphabetically
if (global == -1) {
TreeSet treeSet = new TreeSet();
for (int i = 0; i < catalogs.size(); i++) {
treeSet.add(catalogs.get(i));
}
namespace = (String)treeSet.first();
} else {
namespace = (String)catalogs.get(global);
}
}
return SchemaUtil.getQName(namespace, userSettings.getRequestTableLocalName());
}
public Boolean isRequestOrResponseTable( QName qname ) {
if (SOURCE_DOCUMENT == userSettings.getSourceType() || SOURCE_HTTP_NO_PARAMS == userSettings.getSourceType()) {
return null;
}
boolean retval = qname.equals(getRequestResponseTable());
return new Boolean(retval);
}
public static String globalNamespace = XmlImporterUiPlugin.getDefault().getPluginUtil().getString("XsdAsRelationalImportWizard.globalNamespace"); //$NON-NLS-1$
public String getCatalog( SchemaObject table ) {
String catalog = ""; //$NON-NLS-1$
if (isUsingNamespaces() || isUsingNoCatalog()) {
String namespace = table.getNamespace();
if (namespace == null) {
catalog = globalNamespace;
} else {
catalog = CoreValidationRulesUtil.getValidString(namespace, null, -1);
}
}
if (isUsingFileNames()) {
catalog = table.getFileName();
}
if (isUsingCustom()) {
catalog = (String)getCatalogs().get(0);
}
return catalog;
}
public void setACSMode( boolean acsMode ) {
this.acsMode = acsMode;
}
public boolean getACSMode() {
return acsMode;
}
}