Clover coverage report - JBind Project
Coverage timestamp: Fr Mai 28 2004 11:17:36 CEST
file stats: LOC: 438   Methods: 19
NCLOC: 365   Classes: 2
This license of Clover is provided to support the development of JBind only. Please visit http://www.thecortex.net/clover to obtain a licensed version of Clover.
 
 Source file Conditionals Statements Methods TOTAL
Instantiator.java 83,7% 85,7% 94,7% 85,6%
 1   
 /*
 2   
  * JBind
 3   
  *
 4   
  * Copyright (c) by Stefan Wachter. All rights reserved.
 5   
  *
 6   
  * Usage, modification, and redistribution is subject to license terms that are
 7   
  * available at 'http://www.jbind.org'. The JBind license is like the
 8   
  * 'Apache Software License V 1.1'.
 9   
  */
 10   
 package org.jbind.xml.schema.reader;
 11   
 
 12   
 import java.net.URL;
 13   
 import java.util.ArrayList;
 14   
 import java.util.Collection;
 15   
 import java.util.HashMap;
 16   
 import java.util.HashSet;
 17   
 import java.util.Iterator;
 18   
 import java.util.List;
 19   
 import java.util.Map;
 20   
 import java.util.Set;
 21   
 
 22   
 import org.jbind.xml.Config;
 23   
 import org.jbind.xml.base.IBindingAttributes;
 24   
 import org.jbind.xml.base.IRef;
 25   
 import org.jbind.xml.base.ISymbolspaces;
 26   
 import org.jbind.xml.base.Ref;
 27   
 import org.jbind.xml.core.bridge.IDataImplFactory;
 28   
 import org.jbind.xml.core.bridge.IElementImpl;
 29   
 import org.jbind.xml.core.cmp.IComponent;
 30   
 import org.jbind.xml.core.cmp.IComponentStore;
 31   
 import org.jbind.xml.core.cmp.ISchema;
 32   
 import org.jbind.xml.core.cmp.ISchemaDataAdder;
 33   
 import org.jbind.xml.core.content.IElemRefOrDecl;
 34   
 import org.jbind.xml.core.content.IElemWildcard;
 35   
 import org.jbind.xml.core.data.IAnyTypeData;
 36   
 import org.jbind.xml.core.type.IAnyType;
 37   
 import org.jbind.xml.msg.IConstraintViolations;
 38   
 import org.jbind.xml.msg.XmlException;
 39   
 import org.jbind.xml.msg.XmlMessages;
 40   
 import org.jbind.xml.schema.cmp.Schema;
 41   
 import org.jbind.xml.schema.cmp.Schemas;
 42   
 import org.jbind.xml.schema.instantiation.IJobRef;
 43   
 import org.jbind.xml.schema.instantiation.ISchemaElement;
 44   
 import org.jbind.xml.schema.instantiation.ISchemaParser;
 45   
 
 46   
 public class Instantiator implements IInstantiator, IComponentStore {
 47   
 
 48   
   private Set myLocations = null;
 49   
   private Collection myCreationJobs = null;
 50   
   private Collection myCompletionJobs = null;
 51   
   private Collection myValidationJobs = null;
 52   
 
 53   
   private List mySchemaDataAdditions = null;
 54   
 
 55   
   private Set myParsedUrls = null;
 56   
 
 57   
   /**
 58   
    * Maps references to components that are created but may not (yet) be validated.
 59   
    */
 60   
   private Map myCreatedComponents = null;
 61   
 
 62   
   private boolean myUseBuiltInClassesOnly = true;
 63   
 
 64   
   private ISchema mySchema = null;
 65   
 
 66   
   private ISchemaParser myParser = null;
 67   
   private IDataImplFactory myDataFactory;
 68   
 
 69  199
   public Instantiator(ISchemaParser aParser, IDataImplFactory aDataFactory) {
 70  199
     myParser = aParser;
 71  199
     myDataFactory = aDataFactory;
 72   
   }
 73   
 
 74  24
   public IInstantiator newInstantiator() {
 75  24
     return new Instantiator(myParser, myDataFactory);
 76   
   }
 77   
 
 78  26
   public ISchema getSchema() {
 79  26
     return mySchema;
 80   
   }
 81   
 
 82  223
   public synchronized ISchema readSchema(URL aUrl, boolean aUseBuiltInClassesOnly, String aPackage) throws XmlException {
 83  223
     myUseBuiltInClassesOnly = aUseBuiltInClassesOnly;
 84  223
     myLocations = new HashSet();
 85  223
     myCreationJobs = new ArrayList();
 86  223
     myCompletionJobs = new ArrayList();
 87  223
     myValidationJobs = new ArrayList();
 88  223
     myCreatedComponents = new HashMap();
 89  223
     mySchemaDataAdditions = new ArrayList();
 90  223
     myParsedUrls = new HashSet();
 91  223
     ISchemaElement schemaElement = parseSchema(aUrl, null);
 92  185
     String namespace = schemaElement.getTargetNamespace();
 93  185
     mySchema = new Schema(namespace, schemaElement);
 94  185
     schemaElement.setSchema(mySchema);
 95  185
     URL url = getEffectiveUrl(aUrl);
 96  185
     add(new SchemaJob(this, schemaElement, url));
 97  185
     IConstraintViolations violations = XmlMessages.constraintViolations();
 98  185
     executeJobs(violations);
 99  185
     if (!violations.isEmpty()) {
 100  26
       throw new XmlException(violations);
 101   
     }
 102  159
     String packageName = (null != aPackage) ? aPackage : schemaElement.getStringBindingAttribute(IBindingAttributes.PACKAGE);
 103  159
     if (null == packageName) {
 104  100
       packageName = Config.instance.getPackageForNamespace(namespace);
 105   
     }
 106   
     // Bind the created components.
 107  159
     BindingVisitor bindingVisitor = new BindingVisitor(packageName, myUseBuiltInClassesOnly, violations);
 108  159
     for (Iterator i = mySchema.iterComponents(null); i.hasNext(); ) {
 109  949
       IComponent component = (IComponent)i.next();
 110  949
       component.accept(bindingVisitor);
 111   
     }
 112  159
     if (!violations.isEmpty()) {
 113  0
       throw new XmlException(violations);
 114   
     }
 115  159
     for (Iterator i = mySchemaDataAdditions.iterator(); i.hasNext(); ) {
 116  3327
       SchemaDataAddition addition = (SchemaDataAddition)i.next();
 117  3327
       addition.adder.addSchemaData(this, addition.component, violations);
 118   
     }
 119  159
     if (!violations.isEmpty()) {
 120  3
       throw new XmlException(violations);
 121   
     }
 122  156
     String factoryTypeName = schemaElement.getStringBindingAttribute(IBindingAttributes.FACTORY_TYPE);
 123  156
     if (null != factoryTypeName) {
 124  2
       Ref ref = new Ref(mySchema.getNamespace(), ISymbolspaces.TYPE, factoryTypeName);
 125  2
       IAnyType factoryType = (IAnyType)mySchema.getComponent(ref);
 126  2
       if (null == factoryType) {
 127  0
         violations.add(XmlMessages.schemaTypeNotFound(factoryTypeName, schemaElement));
 128   
       } else {
 129  2
         for (Iterator i = factoryType.getContentModel().iterElements();
 130  6
                 i.hasNext(); ) {
 131  4
           IElemRefOrDecl erd = (IElemRefOrDecl)i.next();
 132  4
           if (!erd.isReference()) {
 133  0
             violations.add(XmlMessages.schemaFactoryMustNotContainElemDecl(erd.getName(), erd));
 134   
           }
 135   
         }
 136  2
         for (Iterator i = factoryType.getContentModel().iterElemWildcards();
 137  2
                 i.hasNext(); ) {
 138  0
           IElemWildcard ew = (IElemWildcard)i.next();
 139  0
           violations.add(XmlMessages.schemaFactoryMustNotContainElemWildcard(ew));
 140   
         }
 141  2
         try {
 142  2
           IElementImpl factoryImpl = myDataFactory.getElementFactoryImpl();
 143  2
           IAnyTypeData factory = factoryType.createData(factoryImpl);
 144  2
           mySchema.setFactory(factory);
 145   
         } catch (XmlException e) {
 146  0
           violations.add(e.getXmlMessage());
 147   
         }
 148   
       }
 149   
     }
 150  156
     if (!violations.isEmpty()) {
 151  0
       throw new XmlException(violations);
 152   
     }
 153  156
     return mySchema;
 154   
   }
 155   
 
 156  448
   private URL getEffectiveUrl(URL aUrl) throws XmlException {
 157  448
     URL url = null;
 158  448
     String stringUrl = Config.instance.resolveUri(aUrl.toString());
 159  448
     if (null == stringUrl) {
 160  448
       url = aUrl;
 161   
     } else {
 162  0
       try {
 163  0
         url = new URL(stringUrl);
 164   
       } catch (Exception e) {
 165  0
         throw new XmlException(XmlMessages.wrappedException(e, null));
 166   
       }
 167   
     }
 168  448
     return url;
 169   
   }
 170   
 
 171  20
   public boolean hasBeenParsed(URL aUrl) throws XmlException {
 172  20
     URL url = getEffectiveUrl(aUrl);
 173  20
     return myParsedUrls.contains(url.toString());
 174   
   }
 175   
 
 176  243
   public ISchemaElement parseSchema(URL aUrl, ISchemaElement aParent) throws XmlException {
 177  243
     URL url = getEffectiveUrl(aUrl);
 178  243
     myParsedUrls.add(url.toString());
 179  243
     return myParser.parseSchema(url, aParent);
 180   
   }
 181   
 
 182  24
   public boolean getUseBuiltInClassesOnly() {
 183  24
     return myUseBuiltInClassesOnly;
 184   
   }
 185   
 
 186  3801
   public void add(IJob aJob) {
 187  3801
     myCreationJobs.add(aJob);
 188   
   }
 189   
 
 190  946
   public void addCreatedComponent(IComponent aComponent, IConstraintViolations aViolations) {
 191  946
     IRef ref = aComponent.getGlobalRef();
 192  946
     if (null != myCreatedComponents.put(ref, aComponent)) {
 193  0
       aViolations.add(XmlMessages.componentNotUnique(ref, aComponent));
 194   
     }
 195   
   }
 196   
 
 197  933
   public void addValidatedComponent(IComponent aComponent, IConstraintViolations aViolations) {
 198  933
     mySchema.setComponent(aComponent, aViolations);
 199   
   }
 200   
 
 201   
   /**
 202   
    * Gets a validated component.
 203   
    */
 204  0
   public IComponent getComponent(IRef aRef) {
 205  0
     IComponent res = null;
 206  0
     if (aRef.getNamespace().equals(mySchema.getNamespace())) {
 207  0
       res = mySchema.getComponent(aRef);
 208   
     } else {
 209  0
       res = Schemas.getInstance().getComponent(aRef);
 210   
     }
 211  0
     return res;
 212   
   }
 213   
 
 214  22373
   public IComponent getComponent(IJobRef aJobRef) {
 215  22373
     IComponent res = null;
 216  22373
     if (aJobRef.getNamespace().equals(mySchema.getNamespace())) {
 217  18139
       if (aJobRef.getMustBeValidated()) {
 218  9620
         res = mySchema.getComponent(aJobRef);
 219   
       } else {
 220  8519
         res = (IComponent)myCreatedComponents.get(aJobRef);
 221   
       }
 222   
     } else {
 223  4234
       res = Schemas.getInstance().getComponent(aJobRef);
 224   
     }
 225  22373
     return res;
 226   
   }
 227   
 
 228   
 
 229  3085
   private Iterator iterReadyCreationJobs() {
 230  3085
     List res = new ArrayList();
 231  3085
     for (Iterator i = myCreationJobs.iterator(); i.hasNext(); ) {
 232  13518
       IJob job = (IJob)i.next();
 233  13518
       boolean isReady = true;
 234  13518
       for (Iterator j = job.iterRefsForCreation(); isReady && j.hasNext(); ) {
 235  15558
         IJobRef ref = (IJobRef)j.next();
 236  15558
         if (null == getComponent(ref)) {
 237  9743
           isReady = false;
 238   
         }
 239   
       }
 240  13518
       if (isReady) {
 241  3775
         i.remove();
 242  3775
         res.add(job);
 243   
       }
 244   
     }
 245  3085
     return res.iterator();
 246   
   }
 247   
 
 248   
   /**
 249   
    * Iterates all jobs that are ready for the completion step.
 250   
    * A job is ready for the completion step if all its references for completion
 251   
    * can be resolved and all of its sub jobs are validated. The iterated jobs
 252   
    * are removed from their containing collection.
 253   
    *
 254   
    * @return <i>(required)</i>.
 255   
    */
 256  2033
   private Iterator iterReadyCompletionJobs() {
 257  2033
     List res = new ArrayList();
 258  2033
     for (Iterator i = myCompletionJobs.iterator(); i.hasNext(); ) {
 259  14007
       IJob job = (IJob)i.next();
 260  14007
       if (job.checkSubJobsValidated()) {
 261  4525
         boolean isReady = true;
 262  4525
         for (Iterator j = job.iterRefsForCompletion(); isReady && j.hasNext(); ) {
 263  1751
           IJobRef ref = (IJobRef)j.next();
 264  1751
           if (null == getComponent(ref)) {
 265  805
             isReady = false;
 266   
           }
 267   
         }
 268  4525
         if (isReady) {
 269  3720
           i.remove();
 270  3720
           res.add(job);
 271   
         }
 272   
       }
 273   
     }
 274  2033
     return res.iterator();
 275   
   }
 276   
 
 277   
 
 278  1109
   private Iterator iterReadyValidationJobs() {
 279  1109
     List res = new ArrayList();
 280  1109
     for (Iterator i = myValidationJobs.iterator(); i.hasNext(); ) {
 281  3716
       IJob job = (IJob)i.next();
 282  3716
       boolean isReady = true;
 283  3716
       for (Iterator j = job.iterRefsForValidation(); isReady && j.hasNext(); ) {
 284  942
         IJobRef ref = (IJobRef)j.next();
 285  942
         if (null == getComponent(ref)) {
 286  0
           isReady = false;
 287   
         }
 288   
       }
 289  3716
       if (isReady) {
 290  3716
         i.remove();
 291  3716
         res.add(job);
 292   
       }
 293   
     }
 294  1109
     return res.iterator();
 295   
   }
 296   
 
 297   
 
 298  185
   private void executeJobs(IConstraintViolations aViolations) {
 299  185
     Collection errorJobs = new ArrayList();
 300   
 
 301  185
     boolean validatedSomething;
 302   
 
 303  185
     do {
 304  1109
       validatedSomething = false;
 305   
 
 306  1109
       boolean completedSomething;
 307   
 
 308  1109
       do {
 309  2033
         completedSomething = false;
 310   
 
 311  2033
         boolean createdSomething;
 312   
 
 313  2033
         do {
 314  3085
           createdSomething = false;
 315   
 
 316  3085
           for (Iterator i = iterReadyCreationJobs(); i.hasNext(); ) {
 317  3775
             createdSomething = true;
 318  3775
             IConstraintViolations violations = XmlMessages.constraintViolations();
 319  3775
             IJob job = (IJob)i.next();
 320  3775
             try {
 321  3775
               job.executeCreation(violations);
 322   
             } catch (XmlException e) {
 323  0
               violations.add(e.getXmlMessage());
 324   
             }
 325  3775
             if (violations.isEmpty()) {
 326  3773
               myCompletionJobs.add(job);
 327   
             } else {
 328  2
               errorJobs.add(job);
 329  2
               violations.addTo(aViolations);
 330   
             }
 331   
           }
 332  3085
         } while (createdSomething);
 333   
 
 334  2033
         for (Iterator i = iterReadyCompletionJobs(); i.hasNext(); ) {
 335  3720
           completedSomething = true;
 336  3720
           IConstraintViolations violations = XmlMessages.constraintViolations();
 337  3720
           IJob job = (IJob)i.next();
 338  3720
           try {
 339  3720
             job.executeCompletion(violations);
 340   
           } catch (XmlException e) {
 341  0
             violations.add(e.getXmlMessage());
 342   
           }
 343  3720
           if (violations.isEmpty()) {
 344  3716
             myValidationJobs.add(job);
 345   
           } else {
 346  4
             errorJobs.add(job);
 347  4
             violations.addTo(aViolations);
 348   
           }
 349   
         }
 350  2033
       } while (completedSomething);
 351   
 
 352  1109
       for (Iterator i = iterReadyValidationJobs(); i.hasNext(); ) {
 353  3716
         validatedSomething = true;
 354  3716
         IConstraintViolations violations = XmlMessages.constraintViolations();
 355  3716
         IJob job = (IJob)i.next();
 356  3716
         try {
 357  3716
           job.executeValidation(violations);
 358   
         } catch (XmlException e) {
 359  0
           violations.add(e.getXmlMessage());
 360   
         }
 361  3716
         if (!violations.isEmpty()) {
 362  0
           errorJobs.add(job);
 363  0
           violations.addTo(aViolations);
 364   
         }
 365   
       }
 366   
 
 367  1109
     } while (validatedSomething);
 368   
 
 369  185
     for (Iterator i = myCreationJobs.iterator(); i.hasNext(); ) {
 370  26
       IJob job = (IJob)i.next();
 371  26
       boolean openRef = false;
 372  26
       for (Iterator j = job.iterRefsForCreation(); j.hasNext(); ) {
 373  38
         IJobRef jobRef = (IJobRef)j.next();
 374  38
         if (null == getComponent(jobRef)) {
 375  26
           aViolations.add(XmlMessages.openReference(jobRef, jobRef));
 376  26
           openRef = true;
 377   
         }
 378   
       }
 379   
       assert openRef;
 380   
     }
 381   
 
 382  185
     for (Iterator i = myCompletionJobs.iterator(); i.hasNext(); ) {
 383  53
       IJob job = (IJob)i.next();
 384  53
       boolean openRef = false;
 385  53
       for (Iterator j = job.iterRefsForCompletion(); j.hasNext(); ) {
 386  28
         IJobRef jobRef = (IJobRef)j.next();
 387  28
         if (null == getComponent(jobRef)) {
 388  5
           aViolations.add(XmlMessages.openReference(jobRef, jobRef));
 389  5
           openRef = true;
 390   
         }
 391   
       }
 392  53
       StringBuffer subJobs = new StringBuffer();
 393  53
       for (Iterator j = job.iterSubJobs(); j.hasNext(); ) {
 394  113
         IJob subJob = (IJob)j.next();
 395  113
         if (!subJob.getIsValidated()) {
 396  59
           if (subJobs.length() != 0) {
 397  9
             subJobs.append(", ");
 398   
           }
 399  59
           subJobs.append(subJob);
 400   
         }
 401   
       }
 402   
       assert openRef || (subJobs.length() > 0);
 403  53
       if (subJobs.length() > 0) {
 404  50
         aViolations.add(XmlMessages.openCompletionJob(job, subJobs, job));
 405   
       }
 406   
 
 407   
     }
 408   
 
 409  185
     for (Iterator i = myValidationJobs.iterator(); i.hasNext(); ) {
 410  0
       IJob job = (IJob)i.next();
 411  0
       boolean openRef = false;
 412  0
       for (Iterator j = job.iterRefsForValidation(); j.hasNext(); ) {
 413  0
         IJobRef jobRef = (IJobRef)j.next();
 414  0
         if (null == getComponent(jobRef)) {
 415  0
           aViolations.add(XmlMessages.openReference(jobRef, jobRef));
 416  0
           openRef = true;
 417   
         }
 418   
       }
 419   
       assert openRef;
 420   
     }
 421   
 
 422   
   }
 423   
 
 424  3525
   public void addSchemaDataAddition(IComponent aComponent, ISchemaDataAdder anAdder) {
 425  3525
     mySchemaDataAdditions.add(new SchemaDataAddition(aComponent, anAdder));
 426   
   }
 427   
 
 428   
   private static class SchemaDataAddition {
 429   
     public IComponent component = null;
 430   
     public ISchemaDataAdder adder = null;
 431  3525
     public SchemaDataAddition(IComponent aComponent, ISchemaDataAdder anAdder) {
 432  3525
       component = aComponent;
 433  3525
       adder = anAdder;
 434   
     }
 435   
   }
 436   
 
 437   
 }
 438