src/share/jaxws_classes/com/sun/xml/internal/bind/v2/runtime/unmarshaller/UnmarshallingContext.java

changeset 397
b99d7e355d4b
parent 286
f50545b5e2f1
child 637
9c07ef4934dd
child 650
121e938cb9c3
     1.1 --- a/src/share/jaxws_classes/com/sun/xml/internal/bind/v2/runtime/unmarshaller/UnmarshallingContext.java	Thu Aug 08 10:10:38 2013 -0700
     1.2 +++ b/src/share/jaxws_classes/com/sun/xml/internal/bind/v2/runtime/unmarshaller/UnmarshallingContext.java	Fri Aug 23 09:57:21 2013 +0100
     1.3 @@ -1,5 +1,5 @@
     1.4  /*
     1.5 - * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
     1.6 + * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
     1.7   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     1.8   *
     1.9   * This code is free software; you can redistribute it and/or modify it
    1.10 @@ -35,6 +35,8 @@
    1.11  import java.util.List;
    1.12  import java.util.Map;
    1.13  import java.util.concurrent.Callable;
    1.14 +import java.util.logging.Level;
    1.15 +import java.util.logging.Logger;
    1.16  
    1.17  import javax.xml.XMLConstants;
    1.18  import javax.xml.bind.JAXBElement;
    1.19 @@ -51,6 +53,7 @@
    1.20  import com.sun.istack.internal.Nullable;
    1.21  import com.sun.istack.internal.SAXParseException2;
    1.22  import com.sun.xml.internal.bind.IDResolver;
    1.23 +import com.sun.xml.internal.bind.Util;
    1.24  import com.sun.xml.internal.bind.api.AccessorException;
    1.25  import com.sun.xml.internal.bind.api.ClassResolver;
    1.26  import com.sun.xml.internal.bind.unmarshaller.InfosetScanner;
    1.27 @@ -59,6 +62,8 @@
    1.28  import com.sun.xml.internal.bind.v2.runtime.Coordinator;
    1.29  import com.sun.xml.internal.bind.v2.runtime.JAXBContextImpl;
    1.30  import com.sun.xml.internal.bind.v2.runtime.JaxBeanInfo;
    1.31 +import java.util.logging.Level;
    1.32 +import java.util.logging.Logger;
    1.33  
    1.34  import org.xml.sax.ErrorHandler;
    1.35  import org.xml.sax.SAXException;
    1.36 @@ -76,6 +81,8 @@
    1.37  public final class UnmarshallingContext extends Coordinator
    1.38      implements NamespaceContext, ValidationEventHandler, ErrorHandler, XmlVisitor, XmlVisitor.TextPredictor {
    1.39  
    1.40 +    private static final Logger logger = Logger.getLogger(UnmarshallingContext.class.getName());
    1.41 +
    1.42      /**
    1.43       * Root state.
    1.44       */
    1.45 @@ -177,6 +184,14 @@
    1.46      public @Nullable ClassLoader classLoader;
    1.47  
    1.48      /**
    1.49 +     * The variable introduced to avoid reporting n^10 similar errors.
    1.50 +     * After error is reported counter is decremented. When it became 0 - errors should not be reported any more.
    1.51 +     *
    1.52 +     * volatile is required to ensure that concurrent threads will see changed value
    1.53 +     */
    1.54 +    private static volatile int errorsCounter = 10;
    1.55 +
    1.56 +    /**
    1.57       * State information for each element.
    1.58       */
    1.59      public final class State {
    1.60 @@ -260,21 +275,32 @@
    1.61              return UnmarshallingContext.this;
    1.62          }
    1.63  
    1.64 +        @SuppressWarnings("LeakingThisInConstructor")
    1.65          private State(State prev) {
    1.66              this.prev = prev;
    1.67 -            if(prev!=null)
    1.68 +            if (prev!=null) {
    1.69                  prev.next = this;
    1.70 +            }
    1.71          }
    1.72  
    1.73          private void push() {
    1.74 -            if(next==null)
    1.75 +            if (logger.isLoggable(Level.FINEST)) {
    1.76 +                logger.log(Level.FINEST, "State.push");
    1.77 +            }
    1.78 +            if (next==null) {
    1.79 +                assert current == this;
    1.80                  allocateMoreStates();
    1.81 +            }
    1.82 +            nil = false;
    1.83              State n = next;
    1.84              n.numNsDecl = nsLen;
    1.85              current = n;
    1.86          }
    1.87  
    1.88          private void pop() {
    1.89 +            if (logger.isLoggable(Level.FINEST)) {
    1.90 +                logger.log(Level.FINEST, "State.pop");
    1.91 +            }
    1.92              assert prev!=null;
    1.93              loader = null;
    1.94              nil = false;
    1.95 @@ -381,8 +407,9 @@
    1.96          assert current.next==null;
    1.97  
    1.98          State s = current;
    1.99 -        for( int i=0; i<8; i++ )
   1.100 +        for (int i=0; i<8; i++) {
   1.101              s = new State(s);
   1.102 +        }
   1.103      }
   1.104  
   1.105      public void clearStates() {
   1.106 @@ -436,6 +463,7 @@
   1.107          }
   1.108      }
   1.109  
   1.110 +    @Override
   1.111      public void startDocument(LocatorEx locator, NamespaceContext nsContext) throws SAXException {
   1.112          if(locator!=null)
   1.113              this.locator = locator;
   1.114 @@ -449,8 +477,6 @@
   1.115          isUnmarshalInProgress = true;
   1.116          nsLen=0;
   1.117  
   1.118 -        setThreadAffinity();
   1.119 -
   1.120          if(expectedType!=null)
   1.121              root.loader = EXPECTED_TYPE_ROOT_LOADER;
   1.122          else
   1.123 @@ -459,6 +485,7 @@
   1.124          idResolver.startDocument(this);
   1.125      }
   1.126  
   1.127 +    @Override
   1.128      public void startElement(TagName tagName) throws SAXException {
   1.129          pushCoordinator();
   1.130          try {
   1.131 @@ -486,6 +513,7 @@
   1.132          current.loader.startElement(current,tagName);
   1.133      }
   1.134  
   1.135 +    @Override
   1.136      public void text(CharSequence pcdata) throws SAXException {
   1.137          State cur = current;
   1.138          pushCoordinator();
   1.139 @@ -502,6 +530,7 @@
   1.140          }
   1.141      }
   1.142  
   1.143 +    @Override
   1.144      public final void endElement(TagName tagName) throws SAXException {
   1.145          pushCoordinator();
   1.146          try {
   1.147 @@ -526,6 +555,7 @@
   1.148          }
   1.149      }
   1.150  
   1.151 +    @Override
   1.152      public void endDocument() throws SAXException {
   1.153          runPatchers();
   1.154          idResolver.endDocument();
   1.155 @@ -537,14 +567,13 @@
   1.156  
   1.157          // at the successful completion, scope must be all closed
   1.158          assert root==current;
   1.159 -
   1.160 -        resetThreadAffinity();
   1.161      }
   1.162  
   1.163      /**
   1.164       * You should be always calling this through {@link TextPredictor}.
   1.165       */
   1.166      @Deprecated
   1.167 +    @Override
   1.168      public boolean expectText() {
   1.169          return current.loader.expectText;
   1.170      }
   1.171 @@ -553,10 +582,12 @@
   1.172       * You should be always getting {@link TextPredictor} from {@link XmlVisitor}.
   1.173       */
   1.174      @Deprecated
   1.175 +    @Override
   1.176      public TextPredictor getPredictor() {
   1.177          return this;
   1.178      }
   1.179  
   1.180 +    @Override
   1.181      public UnmarshallingContext getContext() {
   1.182          return this;
   1.183      }
   1.184 @@ -650,6 +681,7 @@
   1.185                      event.getLinkedException() ) );
   1.186      }
   1.187  
   1.188 +    @Override
   1.189      public boolean handleEvent(ValidationEvent event) {
   1.190          try {
   1.191              // if the handler says "abort", we will not return the object.
   1.192 @@ -680,6 +712,7 @@
   1.193          handleEvent(new ValidationEventImpl(ValidationEvent.ERROR,msg,locator.getLocation()));
   1.194      }
   1.195  
   1.196 +    @Override
   1.197      protected ValidationEventLocator getLocation() {
   1.198          return locator.getLocation();
   1.199      }
   1.200 @@ -801,6 +834,7 @@
   1.201      private String[] nsBind = new String[16];
   1.202      private int nsLen=0;
   1.203  
   1.204 +    @Override
   1.205      public void startPrefixMapping( String prefix, String uri ) {
   1.206          if(nsBind.length==nsLen) {
   1.207              // expand the buffer
   1.208 @@ -811,6 +845,7 @@
   1.209          nsBind[nsLen++] = prefix;
   1.210          nsBind[nsLen++] = uri;
   1.211      }
   1.212 +    @Override
   1.213      public void endPrefixMapping( String prefix ) {
   1.214          nsLen-=2;
   1.215      }
   1.216 @@ -868,6 +903,7 @@
   1.217  
   1.218      //  NamespaceContext2 implementation
   1.219      //
   1.220 +    @Override
   1.221      public Iterator<String> getPrefixes(String uri) {
   1.222          // TODO: could be implemented much faster
   1.223          // wrap it into unmodifiable list so that the remove method
   1.224 @@ -899,6 +935,7 @@
   1.225          return a;
   1.226      }
   1.227  
   1.228 +    @Override
   1.229      public String getPrefix(String uri) {
   1.230          if( uri==null )
   1.231              throw new IllegalArgumentException();
   1.232 @@ -919,6 +956,7 @@
   1.233          return null;
   1.234      }
   1.235  
   1.236 +    @Override
   1.237      public String getNamespaceURI(String prefix) {
   1.238          if (prefix == null)
   1.239              throw new IllegalArgumentException();
   1.240 @@ -1059,6 +1097,7 @@
   1.241              return getInstance().getJAXBContext().getValidRootNames();
   1.242          }
   1.243  
   1.244 +        @Override
   1.245          public void receive(State state, Object o) {
   1.246               if(state.backup!=null) {
   1.247                  ((JAXBElement<Object>)state.backup).setValue(o);
   1.248 @@ -1095,6 +1134,7 @@
   1.249              state.loader = new XsiNilLoader(context.expectedType.getLoader(null,true));
   1.250          }
   1.251  
   1.252 +        @Override
   1.253          public void receive(State state, Object o) {
   1.254              JAXBElement e = (JAXBElement)state.target;
   1.255              e.setValue(o);
   1.256 @@ -1233,4 +1273,27 @@
   1.257          return null;
   1.258      }
   1.259  
   1.260 +    /**
   1.261 +     * Based on current {@link Logger} {@link Level} and errorCounter value determines if error should be reported.
   1.262 +     *
   1.263 +     * If the method called and return true it is expected that error will be reported. And that's why
   1.264 +     * errorCounter is automatically decremented during the check.
   1.265 +     *
   1.266 +     * NOT THREAD SAFE!!! In case of heave concurrency access several additional errors could be reported. It's not expected to be the
   1.267 +     * problem. Otherwise add synchronization here.
   1.268 +     *
   1.269 +     * @return true in case if {@link Level#FINEST} is set OR we haven't exceed errors reporting limit.
   1.270 +     */
   1.271 +    public boolean shouldErrorBeReported() throws SAXException {
   1.272 +        if (logger.isLoggable(Level.FINEST))
   1.273 +            return true;
   1.274 +
   1.275 +        if (errorsCounter >= 0) {
   1.276 +            --errorsCounter;
   1.277 +            if (errorsCounter == 0) // it's possible to miss this because of concurrency. If required add synchronization here
   1.278 +                handleEvent(new ValidationEventImpl(ValidationEvent.WARNING, Messages.ERRORS_LIMIT_EXCEEDED.format(),
   1.279 +                        getLocator().getLocation(), null), true);
   1.280 +        }
   1.281 +        return errorsCounter >= 0;
   1.282 +    }
   1.283  }

mercurial