@Override public String getNewBagType() throws IncompatibleTypes { try { return DescriptorUtils.findSumType(getClasses()).getUnqualifiedName(); } catch (MetaDataException e) { throw new IncompatibleTypes(e); } }
@Override public String getNewBagType() throws IncompatibleTypes { try { ClassDescriptor leftType = findSumType(getClasses()); // We have to check these individually, because of multiple inheritance on the // left. We could, for example have Employees on the left, and subtract Things and // HasAddresses from them, even though there is no common type of Thing and // HasAddress. for (InterMineBag bag: excluded) { // Just check that it makes sense to subtract the rights from the lefts, // ie. that there is some kind of common type here at all. findIntersectionType(asList(leftType, model.getClassDescriptorByName(bag.getType()))); } // But in all cases, the final type is the left type. return leftType.getUnqualifiedName(); } catch (MetaDataException e) { throw new IncompatibleTypes(e); } }
List<ClassDescriptor> commonTypes = findCommonClasses(classes); ClassDescriptor commonSuperType = commonTypes.get(0); break; ClassDescriptor nextCommonSuperType = findSumType(copyOfClasses); isLineage = nextCommonSuperType != lastCommonType; lastCommonType = nextCommonSuperType; ClassDescriptor mostSpecific = sortClassesBySpecificity(classes).get(0); return mostSpecific; } else {
@Override public String getNewBagType() throws IncompatibleTypes { try { return DescriptorUtils.findIntersectionType(getClasses()).getUnqualifiedName(); } catch (MetaDataException e) { throw new IncompatibleTypes(e); } }
/** * Find the ClassDescriptor for the type that any random element selected from a collection * of objects must be an instance of, where each object is an instance of one of the classes * represented by the class descriptors in the input collection. This method does not * consider any of the sub-types of the classes in question. * * eg: * <dl> * <dt>Given <code>[Employee, Manager, CEO]</code></dt> * <dd>returns <code>Employee</code></dd> * <dt>Given <code>[CEO, Company]</code></dt> * <dd>returns <code>HasAddress</code></dd> * <dt>Given <code>[HasAddress, Employable]</code></dt> * <dd>throws an exception</dd> * <dt>Given <code>[]</code></dt> * <dd>throws an exception</dd> * </dl> * @param classes The classes to consider. * @return The lowest common denominator. * @throws MetaDataException if no such type exists. */ public static ClassDescriptor findSumType(Collection<ClassDescriptor> classes) throws MetaDataException { return findCommonClasses(classes).get(0); }
throw new MetaDataException("No common type"); return sortClassesBySpecificity(superClasses);
@Override public String getNewBagType() throws IncompatibleTypes { try { return DescriptorUtils.findIntersectionType(getClasses()).getUnqualifiedName(); } catch (MetaDataException e) { throw new IncompatibleTypes(e); } }
/** * Find the ClassDescriptor for the type that any random element selected from a collection * of objects must be an instance of, where each object is an instance of one of the classes * represented by the class descriptors in the input collection. This method does not * consider any of the sub-types of the classes in question. * * eg: * <dl> * <dt>Given <code>[Employee, Manager, CEO]</code></dt> * <dd>returns <code>Employee</code></dd> * <dt>Given <code>[CEO, Company]</code></dt> * <dd>returns <code>HasAddress</code></dd> * <dt>Given <code>[HasAddress, Employable]</code></dt> * <dd>throws an exception</dd> * <dt>Given <code>[]</code></dt> * <dd>throws an exception</dd> * </dl> * @param classes The classes to consider. * @return The lowest common denominator. * @throws MetaDataException if no such type exists. */ public static ClassDescriptor findSumType(Collection<ClassDescriptor> classes) throws MetaDataException { return findCommonClasses(classes).get(0); }
throw new MetaDataException("No common type"); return sortClassesBySpecificity(superClasses);
@Override public String getNewBagType() throws IncompatibleTypes { try { return DescriptorUtils.findSumType(getClasses()).getUnqualifiedName(); } catch (MetaDataException e) { throw new IncompatibleTypes(e); } }
List<ClassDescriptor> commonTypes = findCommonClasses(classes); ClassDescriptor commonSuperType = commonTypes.get(0); break; ClassDescriptor nextCommonSuperType = findSumType(copyOfClasses); isLineage = nextCommonSuperType != lastCommonType; lastCommonType = nextCommonSuperType; ClassDescriptor mostSpecific = sortClassesBySpecificity(classes).get(0); return mostSpecific; } else {
@Override public String getNewBagType() throws IncompatibleTypes { try { ClassDescriptor leftType = findSumType(getClasses()); // We have to check these individually, because of multiple inheritance on the // left. We could, for example have Employees on the left, and subtract Things and // HasAddresses from them, even though there is no common type of Thing and // HasAddress. for (InterMineBag bag: excluded) { // Just check that it makes sense to subtract the rights from the lefts, // ie. that there is some kind of common type here at all. findIntersectionType(asList(leftType, model.getClassDescriptorByName(bag.getType()))); } // But in all cases, the final type is the left type. return leftType.getUnqualifiedName(); } catch (MetaDataException e) { throw new IncompatibleTypes(e); } }
/** * Test that the most specific common type of a branching tree is the root. * * ie: * <pre> * A * | * [?] * / \ * C D * </pre> */ @Test public void testBranchingTreeMissingSpecificType() throws MetaDataException { withClasses("Thing", "Employee", "Contractor"); String common = DescriptorUtils.findIntersectionType(classes).getUnqualifiedName(); assertEquals("Employable", common); } }
@Override public String getNewBagType() throws IncompatibleTypes { try { return DescriptorUtils.findSumType(getClasses()).getUnqualifiedName(); } catch (MetaDataException e) { throw new IncompatibleTypes(e); } }
/** * Test that the most specific type of a lineage is the descendent. * * ie: * <pre> * A * \ * B * \ * [C] * </pre> */ @Test public void testMostSpecificType() throws MetaDataException { withClasses("Employable", "Employee", "Manager"); String common = DescriptorUtils.findIntersectionType(classes).getUnqualifiedName(); assertEquals(common, "Manager"); }
@Override public String getNewBagType() throws IncompatibleTypes { try { return DescriptorUtils.findSumType(getClasses()).getUnqualifiedName(); } catch (MetaDataException e) { throw new IncompatibleTypes(e); } }
/** * Test that the most specific common type of a branching tree is the root. * * ie: * <pre> * A * | * [B] * / \ * C D * </pre> */ @Test public void testBranchingTreeSpecificType() throws MetaDataException { withClasses("Thing", "Employable", "Employee", "Contractor"); String common = DescriptorUtils.findIntersectionType(classes).getUnqualifiedName(); assertEquals("Employable", common); }
@Test public void testNull() throws MetaDataException { classes = null; try { DescriptorUtils.findSumType(classes); fail("No exception thrown"); } catch (IllegalArgumentException e) { // Expected behaviour. } }
/** * Test that we get exceptions with multiply branching rootless trees too. * * ie: * <pre> * [?] * / | \ * B C E * | * D * </pre> */ @Test public void testClansSpecificType() { withClasses("Employee", "Manager", "HasAddress", "Address"); try { String common = DescriptorUtils.findIntersectionType(classes).getUnqualifiedName(); fail("Expected an exception. Got " + common); } catch (MetaDataException e) { // Expected behaviour. } }
@Test public void testEmptySet() { try { DescriptorUtils.findSumType(classes); fail("No exception thrown"); } catch (MetaDataException e) { // Expected behaviour. } }