/** * Constructs a new aggregate descriptor with the given category, e.g. "CONTENT". * * @param designation the descriptor type, e.g. "CONTENT" * @throws BadDataException if the designation is invalid. */ public DescAggregate(String designation) throws BadDataException { super(); idList = new TreeSet(); if (!Descriptor.isCategory(designation)) { throw new BadDataException("Bad descriptor category -- " + designation); } else { setCategory(designation); } }
/** * 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; }