/** * Checks if the given adaptation is valid. An adaptation is only valid as * part of a composite if the adaptor type is a subtype of the source type. */ private static boolean isValidAdaptation(ElementKey<?, ?> source, ElementKey<?, ?> adaptor) { Class<?> sourceType = source.getElementType(); Class<?> adaptorType = adaptor.getElementType(); if (sourceType == adaptorType) { return false; } return sourceType.isAssignableFrom(adaptorType); }
/** * Checks if the given adaptation is valid. An adaptation is only valid as * part of a composite if the adaptor type is a subtype of the source type. */ private static boolean isValidAdaptation(ElementKey<?, ?> source, ElementKey<?, ?> adaptor) { Class<?> sourceType = source.getElementType(); Class<?> adaptorType = adaptor.getElementType(); if (sourceType == adaptorType) { return false; } return sourceType.isAssignableFrom(adaptorType); }
/** * Checks if the given adaptation is valid. An adaptation is only valid as * part of a composite if the adaptor type is a subtype of the source type. */ private static boolean isValidAdaptation(ElementKey<?, ?> source, ElementKey<?, ?> adaptor) { Class<?> sourceType = source.getElementType(); Class<?> adaptorType = adaptor.getElementType(); if (sourceType == adaptorType) { return false; } return sourceType.isAssignableFrom(adaptorType); }
/** * Creates a collection based on the given key. */ private <T extends Element> Collection<T> createCollection( ElementKey<?, ?> key) { // is part of resolve? Class<?> elementType = key.getElementType(); if (Category.class.isAssignableFrom(elementType)) { return Sets.newLinkedHashSet(); } else { return Lists.newArrayList(); } }
/** * Creates a collection based on the given key. */ private <T extends Element> Collection<T> createCollection( ElementKey<?, ?> key) { // is part of resolve? Class<?> elementType = key.getElementType(); if (Category.class.isAssignableFrom(elementType)) { return Sets.newLinkedHashSet(); } else { return Lists.newArrayList(); } }
/** * Creates a collection based on the given key. */ private <T extends Element> Collection<T> createCollection( ElementKey<?, ?> key) { // is part of resolve? Class<?> elementType = key.getElementType(); if (Category.class.isAssignableFrom(elementType)) { return Sets.newLinkedHashSet(); } else { return Lists.newArrayList(); } }
/** * Calculates the actual key that should be used for adding an element. This * uses the ID and datatype of the key, but if the element types are in the * same type hierarchy the narrowest element type is used. */ private ElementKey<?, ?> calculateKey(ElementKey<?, ?> key, ElementKey<?, ?> sourceKey) { Class<?> keyType = key.getElementType(); Class<? extends Element> sourceType = sourceKey.getElementType(); // If the sourceType is a subtype of the key type, we want to use it // as the type of element that we create, because it is more specific but // still compatible. if (keyType != sourceType && keyType.isAssignableFrom(sourceType)) { key = ElementKey.of(key.getId(), key.getDatatype(), sourceType); } return key; }
/** * Calculates the actual key that should be used for adding an element. This * uses the ID and datatype of the key, but if the element types are in the * same type hierarchy the narrowest element type is used. */ private ElementKey<?, ?> calculateKey(ElementKey<?, ?> key, ElementKey<?, ?> sourceKey) { Class<?> keyType = key.getElementType(); Class<? extends Element> sourceType = sourceKey.getElementType(); // If the sourceType is a subtype of the key type, we want to use it // as the type of element that we create, because it is more specific but // still compatible. if (keyType != sourceType && keyType.isAssignableFrom(sourceType)) { key = ElementKey.of(key.getId(), key.getDatatype(), sourceType); } return key; }
/** * Calculates the actual key that should be used for adding an element. This * uses the ID and datatype of the key, but if the element types are in the * same type hierarchy the narrowest element type is used. */ private ElementKey<?, ?> calculateKey(ElementKey<?, ?> key, ElementKey<?, ?> sourceKey) { Class<?> keyType = key.getElementType(); Class<? extends Element> sourceType = sourceKey.getElementType(); // If the sourceType is a subtype of the key type, we want to use it // as the type of element that we create, because it is more specific but // still compatible. if (keyType != sourceType && keyType.isAssignableFrom(sourceType)) { key = ElementKey.of(key.getId(), key.getDatatype(), sourceType); } return key; }
/** * Registers the metadata for an element key. This will call the * "registerMetadata" method on the {@link Element} subclass that the key * refers to, if it refers to a subclass. If it refers to Element directly * it will just build the key. * * @throws IllegalArgumentException if the element type does not support a * registration method. */ public MetadataRegistry register(ElementKey<?, ?> key) { if (key != null) { Class<? extends Element> elementType = key.getElementType(); if (Element.class == elementType) { build(key); } else { registerClass(elementType); } } return this; }
/** * Get child element matching the specified key. Will try to adapt the * element to the given key if it is not already an instance of the requested * class. This will fail with an exception if the adaptation was not valid. * * @param <T> the type of element to return * @param childKey the metadata key for the child element to retrieve * @return child element, or {@code null} if none was found * @throws IllegalArgumentException if the key referenced a repeating element */ public <D, T extends Element> T getElement(ElementKey<D, T> childKey) { Element child = getElement(childKey.getId()); if (child == null) { return null; } try { return adapt(childKey, child); } catch (ContentCreationException e) { throw new IllegalArgumentException("Unable to adapt to " + childKey.getElementType(), e); } }
/** * Binds an element key to a specific element subclass. This guarantees that * the key on an element will always have exactly that element's type as its * element type, and not some other element type. This makes it possible to * believe an element's key without needing to check the element type when * looking up metadata. */ private static ElementKey<?, ?> bindKey(ElementKey<?, ?> key, Class<? extends Element> type) { Class<?> keyType = key.getElementType(); if (keyType == type) { return key; } return ElementKey.of(key.getId(), key.getDatatype(), type); }
/** * Binds an element key to a specific element subclass. This guarantees that * the key on an element will always have exactly that element's type as its * element type, and not some other element type. This makes it possible to * believe an element's key without needing to check the element type when * looking up metadata. */ private static ElementKey<?, ?> bindKey(ElementKey<?, ?> key, Class<? extends Element> type) { Class<?> keyType = key.getElementType(); if (keyType == type) { return key; } return ElementKey.of(key.getId(), key.getDatatype(), type); }
/** * Binds an element key to a specific element subclass. This guarantees that * the key on an element will always have exactly that element's type as its * element type, and not some other element type. This makes it possible to * believe an element's key without needing to check the element type when * looking up metadata. */ private static ElementKey<?, ?> bindKey(ElementKey<?, ?> key, Class<? extends Element> type) { Class<?> keyType = key.getElementType(); if (keyType == type) { return key; } return ElementKey.of(key.getId(), key.getDatatype(), type); }
/** * Merges the key from the metadata with the source key to get the "real" * key for a moved element. */ private static ElementKey<?, ?> mergeKeys(ElementKey<?, ?> sourceKey, ElementKey<?, ?> metadataKey) { if (!metadataKey.getId().equals(sourceKey.getId())) { return ElementKey.of(metadataKey.getId(), sourceKey.getDatatype(), sourceKey.getElementType()); } return sourceKey; } }
/** * Merges the key from the metadata with the source key to get the "real" * key for a moved element. */ private static ElementKey<?, ?> mergeKeys(ElementKey<?, ?> sourceKey, ElementKey<?, ?> metadataKey) { if (!metadataKey.getId().equals(sourceKey.getId())) { return ElementKey.of(metadataKey.getId(), sourceKey.getDatatype(), sourceKey.getElementType()); } return sourceKey; } }
/** * Merges the key from the metadata with the source key to get the "real" * key for a moved element. */ private static ElementKey<?, ?> mergeKeys(ElementKey<?, ?> sourceKey, ElementKey<?, ?> metadataKey) { if (!metadataKey.getId().equals(sourceKey.getId())) { return ElementKey.of(metadataKey.getId(), sourceKey.getDatatype(), sourceKey.getElementType()); } return sourceKey; } }
/** * Calculate the root key for a given element key based on the ID or type. */ private static RootKey get(ElementKey<?, ?> key) { QName id = key.getId(); Class<? extends Element> elementType = key.getElementType(); if (elementType != Element.class) { Class<? extends Element> superClass = getSuper(elementType); while (superClass != Element.class) { elementType = superClass; superClass = getSuper(elementType); } // For element keys using a subclass of Element, index by type. return new RootKey(elementType); } else { // For element keys that reference Element directly, index by root ID. return new RootKey(getRootId(id)); } }
/** * Calculate the root key for a given element key based on the ID or type. */ private static RootKey get(ElementKey<?, ?> key) { QName id = key.getId(); Class<? extends Element> elementType = key.getElementType(); if (elementType != Element.class) { Class<? extends Element> superClass = getSuper(elementType); while (superClass != Element.class) { elementType = superClass; superClass = getSuper(elementType); } // For element keys using a subclass of Element, index by type. return new RootKey(elementType); } else { // For element keys that reference Element directly, index by root ID. return new RootKey(getRootId(id)); } }
/** * Calculate the root key for a given element key based on the ID or type. */ private static RootKey get(ElementKey<?, ?> key) { QName id = key.getId(); Class<? extends Element> elementType = key.getElementType(); if (elementType != Element.class) { Class<? extends Element> superClass = getSuper(elementType); while (superClass != Element.class) { elementType = superClass; superClass = getSuper(elementType); } // For element keys using a subclass of Element, index by type. return new RootKey(elementType); } else { // For element keys that reference Element directly, index by root ID. return new RootKey(getRootId(id)); } }