/** * Parses a value through a path. This will find the element or attribute * that is at the end of the path, and parse the value into the element's * text content or the attribute's value as appropriate. */ public void parse(Element element, ElementMetadata<?, ?> metadata, Object value) throws ParseException { Path bound = path.toAbsolute(metadata); element = createFinalElement(path, element); if (bound.selectsAttribute()) { parseAttributeValue(element, bound.getSelectedElement(), bound.getSelectedAttributeKey(), bound.getSelectedAttribute(), value); } else { parseTextValue(element, bound.getSelectedElement(), value); } } }
/** * Creates a holder for a virtual element based on a path. Because we don't * know if the path is to a single or multiple cardinality element until * runtime, we create a single adapter that can be either and rely on the * runtime checks in the metadata to make sure we use it correctly. */ static VirtualElementHolder of(Path path) { if (path == null) { return null; } ElementAdapter adapter = PathAdapter.elementAdapter(path); return new VirtualElementHolder(adapter, adapter); }
/** * Generate a text value through the path. If the path ends in an element, * the value will be the text content of the final element. If the path * ends in an attribute, the value will be the value of that attribute. */ public Object generate(Element element, ElementMetadata<?, ?> metadata) { Path bound = path.toAbsolute(metadata); element = getFinalElement(bound, element); if (element == null) { return null; } // Generate the value at the end of the path. if (bound.selectsAttribute()) { return generateAttributeValue(element, bound.getSelectedElement(), bound.getSelectedAttributeKey(), bound.getSelectedAttribute()); } else { return generateTextValue(element, bound.getSelectedElement()); } }
checkNotMultiple(childMetadata); children.add(getOrCreateChild(p, childKey)); Element child = getOrCreateChild(parent, childKey); parent = child; parentMetadata = childMetadata;
/** * Parses a single element using this path. This will follow the path until * the second to last element on the path, and then parse into the final * element using the real parent instead of the path's parent. * * elements along it. */ public void parse(Element parent, ElementMetadata<?, ?> parentMetadata, Element element, ElementMetadata<?, ?> metadata) throws ParseException { Preconditions.checkState(path.selectsElement(), "An attribute path cannot be used to parse elements."); parent = createParentElement(path, parent); ElementKey<?, ?> lastKey = path.getSelectedElementKey(); try { Element child = Element.createElement(lastKey, element); parent.addElement(child); } catch (ContentCreationException e) { throw new ParseException(e); } }
/** * Travels along the path, creating any elements that don't exist until it * gets to the second-to-last key along the path. */ static Element createParentElement(Path path, Element rootElement) throws ParseException { Preconditions.checkNotNull(path, "path"); Preconditions.checkNotNull(rootElement, "rootElement"); List<MetadataKey<?>> steps = path.getSteps(); if (steps.isEmpty()) { return null; } Element parent = rootElement; for (int i = 0; i < steps.size() - 1; i++) { ElementKey<?, ?> childKey = (ElementKey<?, ?>) steps.get(i); parent = getOrCreateChild(parent, childKey); } return parent; }
/** * Generates a single element on the parent by using this path. This * will follow the path to its end, and then use that same element content * as the returned element, after wrapping it with the correct key (id). * * elements along it. */ public Element generateSingle(Element parent, ElementMetadata<?, ?> parentMetadata, ElementMetadata<?, ?> metadata) { Preconditions.checkState(path.selectsElement(), "An attribute path cannot be used to generate elements."); Element element = getFinalElement(path, parent); if (element == null) { return null; } try { ElementKey<?, ?> realKey = mergeKeys( element.getElementKey(), metadata.getKey()); return Element.createElement(realKey, element); } catch (ContentCreationException e) { throw new IllegalArgumentException("Invalid metadata", e); } }
/** * Generate multiple elements based on this path. This only allows a single * multiple cardinality element in the path, but that multiple cardinality * element can be anywhere in the path. Once found we only follow single * cardinality children after that point. * * cardinality along the path. */ public Collection<? extends Element> generateMultiple(Element parent, ElementMetadata<?, ?> parentMetadata, ElementMetadata<?, ?> metadata) { Preconditions.checkState(path.selectsElement(), "An attribute path cannot be used to generate elements."); Collection<? extends Element> elements = getFinalElements(path, parent); if (elements.isEmpty()) { return elements; } List<Element> result = Lists.newArrayListWithCapacity(elements.size()); for (Element e : elements) { try { ElementKey<?, ?> realKey = mergeKeys( e.getElementKey(), metadata.getKey()); result.add(Element.createElement(realKey, e)); } catch (ContentCreationException ex) { throw new IllegalArgumentException("Invalid metadata", ex); } } return result; }
Collection<Element> parents = createParentElements( bound, parent, parentMetadata, elements.size());
checkNotMultiple(childMetadata); children.add(getOrCreateChild(p, childKey)); Element child = getOrCreateChild(parent, childKey); parent = child; parentMetadata = childMetadata;
/** * Parses a single element using this path. This will follow the path until * the second to last element on the path, and then parse into the final * element using the real parent instead of the path's parent. * * elements along it. */ public void parse(Element parent, ElementMetadata<?, ?> parentMetadata, Element element, ElementMetadata<?, ?> metadata) throws ParseException { Preconditions.checkState(path.selectsElement(), "An attribute path cannot be used to parse elements."); parent = createParentElement(path, parent); ElementKey<?, ?> lastKey = path.getSelectedElementKey(); try { Element child = Element.createElement(lastKey, element); parent.addElement(child); } catch (ContentCreationException e) { throw new ParseException(e); } }
/** * Travels along the path, creating any elements that don't exist until it * gets to the second-to-last key along the path. */ static Element createParentElement(Path path, Element rootElement) throws ParseException { Preconditions.checkNotNull(path, "path"); Preconditions.checkNotNull(rootElement, "rootElement"); List<MetadataKey<?>> steps = path.getSteps(); if (steps.isEmpty()) { return null; } Element parent = rootElement; for (int i = 0; i < steps.size() - 1; i++) { ElementKey<?, ?> childKey = (ElementKey<?, ?>) steps.get(i); parent = getOrCreateChild(parent, childKey); } return parent; }
/** * Generates a single element on the parent by using this path. This * will follow the path to its end, and then use that same element content * as the returned element, after wrapping it with the correct key (id). * * elements along it. */ public Element generateSingle(Element parent, ElementMetadata<?, ?> parentMetadata, ElementMetadata<?, ?> metadata) { Preconditions.checkState(path.selectsElement(), "An attribute path cannot be used to generate elements."); Element element = getFinalElement(path, parent); if (element == null) { return null; } try { ElementKey<?, ?> realKey = mergeKeys( element.getElementKey(), metadata.getKey()); return Element.createElement(realKey, element); } catch (ContentCreationException e) { throw new IllegalArgumentException("Invalid metadata", e); } }
/** * Generate multiple elements based on this path. This only allows a single * multiple cardinality element in the path, but that multiple cardinality * element can be anywhere in the path. Once found we only follow single * cardinality children after that point. * * cardinality along the path. */ public Collection<? extends Element> generateMultiple(Element parent, ElementMetadata<?, ?> parentMetadata, ElementMetadata<?, ?> metadata) { Preconditions.checkState(path.selectsElement(), "An attribute path cannot be used to generate elements."); Collection<? extends Element> elements = getFinalElements(path, parent); if (elements.isEmpty()) { return elements; } List<Element> result = Lists.newArrayListWithCapacity(elements.size()); for (Element e : elements) { try { ElementKey<?, ?> realKey = mergeKeys( e.getElementKey(), metadata.getKey()); result.add(Element.createElement(realKey, e)); } catch (ContentCreationException ex) { throw new IllegalArgumentException("Invalid metadata", ex); } } return result; }
Collection<Element> parents = createParentElements( bound, parent, parentMetadata, elements.size());
/** * Generate a text value through the path. If the path ends in an element, * the value will be the text content of the final element. If the path * ends in an attribute, the value will be the value of that attribute. */ public Object generate(Element element, ElementMetadata<?, ?> metadata) { Path bound = path.toAbsolute(metadata); element = getFinalElement(bound, element); if (element == null) { return null; } // Generate the value at the end of the path. if (bound.selectsAttribute()) { return generateAttributeValue(element, bound.getSelectedElement(), bound.getSelectedAttributeKey(), bound.getSelectedAttribute()); } else { return generateTextValue(element, bound.getSelectedElement()); } }
/** * Parses a value through a path. This will find the element or attribute * that is at the end of the path, and parse the value into the element's * text content or the attribute's value as appropriate. */ public void parse(Element element, ElementMetadata<?, ?> metadata, Object value) throws ParseException { Path bound = path.toAbsolute(metadata); element = createFinalElement(path, element); if (bound.selectsAttribute()) { parseAttributeValue(element, bound.getSelectedElement(), bound.getSelectedAttributeKey(), bound.getSelectedAttribute(), value); } else { parseTextValue(element, bound.getSelectedElement(), value); } } }
checkNotMultiple(childMetadata); children.add(getOrCreateChild(p, childKey)); Element child = getOrCreateChild(parent, childKey); parent = child; parentMetadata = childMetadata;
/** * Parses a single element using this path. This will follow the path until * the second to last element on the path, and then parse into the final * element using the real parent instead of the path's parent. * * elements along it. */ public void parse(Element parent, ElementMetadata<?, ?> parentMetadata, Element element, ElementMetadata<?, ?> metadata) throws ParseException { Preconditions.checkState(path.selectsElement(), "An attribute path cannot be used to parse elements."); parent = createParentElement(path, parent); ElementKey<?, ?> lastKey = path.getSelectedElementKey(); try { Element child = Element.createElement(lastKey, element); parent.addElement(child); } catch (ContentCreationException e) { throw new ParseException(e); } }
/** * Creates a holder for a virtual element based on a path. Because we don't * know if the path is to a single or multiple cardinality element until * runtime, we create a single adapter that can be either and rely on the * runtime checks in the metadata to make sure we use it correctly. */ static VirtualElementHolder of(Path path) { if (path == null) { return null; } ElementAdapter adapter = PathAdapter.elementAdapter(path); return new VirtualElementHolder(adapter, adapter); }