From 1d6c6a11afe388c62247c09a08836c7d126605a3 Mon Sep 17 00:00:00 2001 From: slaws Date: Fri, 23 Mar 2012 17:29:20 +0000 Subject: TUSCANY-4035 - synchronize schema loading. Thanks for the patch Kaushik. git-svn-id: http://svn.us.apache.org/repos/asf/tuscany@1304516 13f79535-47bb-0310-9956-ffa450edef68 --- .../tuscany/sca/xsd/xml/XSDModelResolver.java | 146 +++++++++++---------- 1 file changed, 78 insertions(+), 68 deletions(-) diff --git a/sca-java-2.x/trunk/modules/xsd/src/main/java/org/apache/tuscany/sca/xsd/xml/XSDModelResolver.java b/sca-java-2.x/trunk/modules/xsd/src/main/java/org/apache/tuscany/sca/xsd/xml/XSDModelResolver.java index 60a59e62ee..535bc1cd44 100644 --- a/sca-java-2.x/trunk/modules/xsd/src/main/java/org/apache/tuscany/sca/xsd/xml/XSDModelResolver.java +++ b/sca-java-2.x/trunk/modules/xsd/src/main/java/org/apache/tuscany/sca/xsd/xml/XSDModelResolver.java @@ -63,6 +63,8 @@ public class XSDModelResolver implements ModelResolver { private Contribution contribution; private Map> map = new HashMap>(); private XmlSchemaCollection schemaCollection; + + private static final byte[] schemaCollectionReadLock = new byte[0]; public XSDModelResolver(Contribution contribution, FactoryExtensionPoint modelFactories) { this.contribution = contribution; @@ -143,84 +145,34 @@ public class XSDModelResolver implements ModelResolver { } private void loadOnDemand(XSDefinition definition) throws IOException { - if (definition.getSchema() != null) { - return; - } - if (definition.getDocument() != null) { - String uri = null; - if (definition.getLocation() != null) { - uri = definition.getLocation().toString(); - } - XmlSchema schema = null; - try { - final XSDefinition finaldef = definition; - final String finaluri = uri; - try { - schema = (XmlSchema) AccessController.doPrivileged(new PrivilegedExceptionAction() { - public XmlSchema run() throws IOException { - return schemaCollection.read(finaldef.getDocument(), finaluri, null); - } - }); - } catch (PrivilegedActionException e) { - throw (IOException) e.getException(); - } - } catch (IOException e) { - throw new ContributionRuntimeException(e); - } catch (RuntimeException e) { - // find original cause of the problem - Throwable cause = e; - while (cause.getCause() != null && cause != cause.getCause()) { - cause = cause.getCause(); - } - throw new ContributionRuntimeException(cause); - } - definition.setSchemaCollection(schemaCollection); - definition.setSchema(schema); - definition.setUnresolved(false); - } else if (definition.getLocation() != null) { - if (definition.getLocation().getFragment() != null) { - // It's an inline schema + + // It might be possible to use a per-XSDModelResolver-instance lock instead of the singleton lock, + // since for a deadlock to occur it would seem to require something along the lines of A imports B imports A. + // Since I'm not sure precisely what the restriction against circular imports is, and since I don't think it's too bad + // to use the singleton lock (after all, loading is, in general, a one-time thing), I'll just use the singleton lock. + synchronized (schemaCollectionReadLock) { + + if (definition.getSchema() != null) { return; } - // Read an XSD document - XmlSchema schema = null; - for (XmlSchema d : schemaCollection.getXmlSchemas()) { - if (isSameNamespace(d.getTargetNamespace(), definition.getNamespace())) { - if (d.getSourceURI().equals(definition.getLocation().toString())) { - schema = d; - break; - } + if (definition.getDocument() != null) { + String uri = null; + if (definition.getLocation() != null) { + uri = definition.getLocation().toString(); } - } - if (schema == null) { - InputSource xsd = null; - final XSDefinition finaldef = definition; + XmlSchema schema = null; try { - try { - xsd = (InputSource) AccessController.doPrivileged(new PrivilegedExceptionAction() { - public InputSource run() throws IOException { - return XMLDocumentHelper.getInputSource(finaldef.getLocation().toURL()); - } - }); - } catch (PrivilegedActionException e) { - throw (IOException) e.getException(); - } - } catch (IOException e) { - throw new ContributionRuntimeException(e); - } - - try { - final InputSource finalxsd = xsd; + final XSDefinition finaldef = definition; + final String finaluri = uri; try { schema = (XmlSchema) AccessController.doPrivileged(new PrivilegedExceptionAction() { public XmlSchema run() throws IOException { - return schemaCollection.read(finalxsd, null); + return schemaCollection.read(finaldef.getDocument(), finaluri, null); } }); } catch (PrivilegedActionException e) { throw (IOException) e.getException(); } - } catch (IOException e) { throw new ContributionRuntimeException(e); } catch (RuntimeException e) { @@ -231,9 +183,67 @@ public class XSDModelResolver implements ModelResolver { } throw new ContributionRuntimeException(cause); } + definition.setSchemaCollection(schemaCollection); + definition.setSchema(schema); + definition.setUnresolved(false); + } else if (definition.getLocation() != null) { + if (definition.getLocation().getFragment() != null) { + // It's an inline schema + return; + } + // Read an XSD document + XmlSchema schema = null; + for (XmlSchema d : schemaCollection.getXmlSchemas()) { + if (isSameNamespace(d.getTargetNamespace(), definition.getNamespace())) { + if (d.getSourceURI().equals(definition.getLocation().toString())) { + schema = d; + break; + } + } + } + if (schema == null) { + InputSource xsd = null; + final XSDefinition finaldef = definition; + try { + try { + xsd = (InputSource) AccessController.doPrivileged(new PrivilegedExceptionAction() { + public InputSource run() throws IOException { + return XMLDocumentHelper.getInputSource(finaldef.getLocation().toURL()); + } + }); + } catch (PrivilegedActionException e) { + throw (IOException) e.getException(); + } + } catch (IOException e) { + throw new ContributionRuntimeException(e); + } + + try { + final InputSource finalxsd = xsd; + try { + schema = (XmlSchema) AccessController.doPrivileged(new PrivilegedExceptionAction() { + public XmlSchema run() throws IOException { + return schemaCollection.read(finalxsd, null); + } + }); + } catch (PrivilegedActionException e) { + throw (IOException) e.getException(); + } + + } catch (IOException e) { + throw new ContributionRuntimeException(e); + } catch (RuntimeException e) { + // find original cause of the problem + Throwable cause = e; + while (cause.getCause() != null && cause != cause.getCause()) { + cause = cause.getCause(); + } + throw new ContributionRuntimeException(cause); + } + } + definition.setSchemaCollection(schemaCollection); + definition.setSchema(schema); } - definition.setSchemaCollection(schemaCollection); - definition.setSchema(schema); } } -- cgit v1.2.3