예제 #1
0
  /**
   * Returns a new descriptor eqiuvalent to this+D. Remember, composition is not commutative for all
   * attributes, and may not exist for some. To compose, remember to call
   * {@linkDescriptor#isComposable() isComposable} first and try both <code>A.compose (B)</code> and
   * <code>B.compose (A)</code>.
   *
   * @param D The Descriptor to compose with this Descriptor.
   * @param scope The attribute scope and mapping.
   * @return A new Descriptor that is equivalent to the composition of this and the argument D.
   * @throws BadDataException if the compose semantics are not correct.
   * @throws UncomposableException this instance of the descriptor cannot be composed. Check
   *     isComposable!
   */
  public Descriptor compose(Descriptor D, EvaluationParameters.ScopeRules scope)
      throws BadDataException, UncomposableException {
    DescAggregate temp = (DescAggregate) this.clone();
    // Unify Descriptions and Spans
    temp.span = temp.span.union(D.getFrameSpan());
    if (D.getClass().equals(DescSingle.class)) {
      if (idList.contains(D.getID()))
        throw new BadDataException("Attempting to compose the same descriptor multiple times");
      else temp.idList.add(D.getID());
    } else {
      // First, check to see if there are any dup ID numbers
      Iterator iterA = idList.iterator();
      Iterator iterB = ((TreeSet) D.getID()).iterator();
      Comparable A = (Comparable) iterA.next();
      Comparable B = (Comparable) iterB.next();

      /// difference will be negative iff A < B, and positive iff A > B.
      // I wish java had operator overloading. I really do.
      double difference = A.compareTo(B);
      while (iterA.hasNext() && iterB.hasNext() && (difference != 0)) {
        while ((difference < 0) && (iterA.hasNext() && iterB.hasNext())) {
          A = (Comparable) iterA.next();
          difference = A.compareTo(B);
        }
        while ((difference > 0) && (iterA.hasNext() && iterB.hasNext())) {
          B = (Comparable) iterB.next();
          difference = A.compareTo(B);
        }
      }
      if (difference == 0)
        // If there was a dup ID num, return 0
        throw new BadDataException("Attempting to compose the same descriptor multiple times");
      temp.idList.addAll(((DescAggregate) D).idList);
    }

    // Unify Attributes
    String errMsg = null;
    for (Iterator iter = scope.getInScopeAttributesFor(temp); iter.hasNext(); ) {
      String currAttrName = (String) iter.next();
      int i = temp.getAttributeIndex(currAttrName, scope.getMap());
      try {
        temp.attributes[i] =
            Attribute.compose(
                this.span,
                this.getAttribute(currAttrName, scope.getMap()),
                D.span,
                D.getAttribute(currAttrName, scope.getMap()));
      } catch (UncomposableException ux) {
        if (errMsg == null) {
          errMsg = ux.getMessage();
        } else {
          errMsg += "\n" + ux.getMessage();
        }
      }
    }
    if (errMsg != null) System.err.println(errMsg + "\n fix your .epf");
    return temp;
  }
예제 #2
0
  /**
   * Serializes an {@link MBeanFeatureInfo} to an {@link ObjectOutputStream}.
   *
   * @serialData For compatibility reasons, an object of this class is serialized as follows.
   *     <ul>
   *       The method {@link ObjectOutputStream#defaultWriteObject defaultWriteObject()} is called
   *       first to serialize the object except the field {@code descriptor} which is declared as
   *       transient. The field {@code descriptor} is serialized as follows:
   *       <ul>
   *         <li>If {@code descriptor} is an instance of the class {@link ImmutableDescriptor}, the
   *             method {@link ObjectOutputStream#write write(int val)} is called to write a byte
   *             with the value {@code 1}, then the method {@link ObjectOutputStream#writeObject
   *             writeObject(Object obj)} is called twice to serialize the field names and the field
   *             values of the {@code descriptor}, respectively as a {@code String[]} and an {@code
   *             Object[]};
   *         <li>Otherwise, the method {@link ObjectOutputStream#write write(int val)} is called to
   *             write a byte with the value {@code 0}, then the method {@link
   *             ObjectOutputStream#writeObject writeObject(Object obj)} is called to serialize
   *             directly the field {@code descriptor}.
   *       </ul>
   *     </ul>
   *
   * @since 1.6
   */
  private void writeObject(ObjectOutputStream out) throws IOException {
    out.defaultWriteObject();

    if (descriptor != null && descriptor.getClass() == ImmutableDescriptor.class) {

      out.write(1);

      final String[] names = descriptor.getFieldNames();

      out.writeObject(names);
      out.writeObject(descriptor.getFieldValues(names));
    } else {
      out.write(0);

      out.writeObject(descriptor);
    }
  }